从多个格式的数值中创建逗号分隔的字符串

问题描述:

我使用逗号分隔值列表创建了一个字符串,但这些数字值具有不同的格式。目前我使用的是这样的:从多个格式的数值中创建逗号分隔的字符串

var values = new StringBuilder(); 
// These are all of type double 
values.AppendFormat("{0:F1},", aLength); 
values.AppendFormat("{0:F4},", anAngle); 
values.AppendFormat("{0:F1},", aHeight); 
values.AppendFormat("{0:F2},{1:F2},", a2DPoint.X, a2DPoint.Y); 
// while these are all of type int 
values.Append(anID).Append(","); 
values.Append(anInt).Append(","); 
values.Append(anotherInt); 
if (aListOfInt.Count > 0) 
{ 
    values.Append(","); 
    values.Append(String.Join(",", aListOfInt)); 
} 

var resultString = values.ToString(); 

这是正确的方法吗?我也可以用String.Join这样做,事先创建一个类似于上面的StringBuilder valuesList<string>,但是会更好吗? 有没有更优雅的方式?

注:我是新来的C#

+6

使用了逗号分隔的字符串十进制数字是一个坏主意 - 有很多文化在他们的数字中使用逗号,这是造成问题的常见原因。例如,可以使用逗号来分隔数千个,甚至是小数点。当转换成字符串和字符串时,至少使用'CultureInfo.InvariantCulture',否则你刚刚破坏了你的应用程序半个星球:) – Luaan 2014-09-04 07:28:01

+0

@Luaan啊,这是一个很好的观点。在这种特殊情况下,这是正在写入文件的信息,用于与旧系统的向后兼容,而旧系统甚至用不同的语言编写。我们正试图改变事情的方式。但是你的评论是我们应该考虑的事情。感谢那。 – alondono 2014-09-04 11:03:09

+2

我认为最好的实现方法是为每个度量单位(即长度,角度,点)创建一个类并覆盖它们的ToString方法,并让多态性为您工作。至于加入这些值,string.Join是最干净的选项。 – brz 2014-09-04 18:41:27

我觉得这确实是相当不错:

var resultString = String.Join(",", new [] 
{ 
    aLength.ToString("F1"), 
    anAngle.ToString("F4"), 
    aHeight.ToString("F1"), 
    a2DPoint.X.ToString("F2"), 
    a2DPoint.Y.ToString("F2"), 
    anID.ToString(), 
    anInt.ToString(), 
    anotherInt.ToString(), 
}.Concat(aListOfInt.Select(x => x.ToString()))); 

试试这个:

var objList = new List<object>(); 
objList.Add(1); 
objList.Add(2.0); 
... 
var resultString = string.Join(",", objList.Cast<string>()); 

把自己的价值观对象的列表,施放值的字符串,并加入值。

但与上述你将失去你的格式。 我有另一种解决方案。我认为这是没有松动的每个值的格式很短的语法:

var stringList = new List<string>{ 
    aLength.ToString("F1"), 
    anAngle.ToString("F4"), 
    ... 
}; 
var resultString = string.Join(",", stringList); 
+1

这对于不同格式的值有什么帮助?即有些人用'F2''别人用'F2'还有其他人用'F4'等等? – Corak 2014-09-04 07:41:06

+0

请参阅第二节。我在同一时间看到了我的错误。首先我想你是指double和int的混合。 – 2014-09-04 07:49:02

+0

@MathiasMüller你的第二部分是我说的“我也可以用'String.Join'来做到这一点”,而不是建立一个'StringBuilder'列表,建立一个'List '并使用'String.Join '。但是这比我上面做的更好吗?由于我是C#的新手,我一直对所有这些问题持怀疑态度 - 更多的C#类,更优雅,更高效。 – alondono 2014-09-04 11:20:36

如果你在寻找什么是更优雅(而不是最优的),你可以尝试这样的事:

//Note the commas in the formats,and that formats and data have the same size. 
List<string> formats = new List<string>(new string[] {"{0:F1},", "{0:F4},", "{0:F2},",{0}}); 
List<object> data=new List<object>(new object[]{4,2,0.12,new object()}); 
StringBuilder resultBuilder=new StringBuilder(); 
for (int i = 0; i < 4; i++) { 
     resultBuilder.AppendFormat(formats[i], data[i]); 
} 
string result = resultBuilder.ToString(); 

只要您对如何设置格式和数据非常小心,除了for循环之外,您无需执行任何其他处理即可将它们“压缩”在一起。我建议在任何a2DPoint类上重写ToString(),这样你就可以将它放到一个单独的格式块中,而不需要特殊的处理,或者将a2DPoint.X和a2DPoint.Y拆分成单独的数据/格式块。不过,这不是最有效的方法。列表占用了空间和时间;如果你提前知道你会有多少条目,阵列可能会更好。

编辑:在注释方法的实施 编辑:添加例子方法的评论称:

public class FormatZipper { 
    //This could be two lists, but it's probably more space/time efficent to use a single list. 
    List<Tuple<string,object>> _entries; 
    StringBuilder _builder; 
    public FormatZipper() { 
     _builder = new StringBuilder(); 
     _entries = new List<Tuple<string, object>>(); 
    } 
    public void AddEntry(string fmt, object data) { 
     _entries.Add(Tuple.Create(fmt, data)); 
    } 

    public string CurrentString { 
     get { 
      _builder.Clear(); 
      foreach (var entry in _entries) { 
       _builder.AppendFormat(entry.Item1, entry.Item2); 
      } 
      return _builder.ToString(); 
     } 
    } 
} 
class Program { 
    static void Main(string[] args) { 
     FormatZipper zipper = new FormatZipper(); 
     zipper.AddEntry("{0:F1},", 1); 
     Console.WriteLine(zipper.CurrentString); 
     zipper.AddEntry("{0:F2,", 1); 
     Console.WriteLine(zipper.CurrentString); 


    } 
} 
+1

尽管看起来很有趣,但这个解决方案的问题在于,正如您所说的,您需要非常小心地设置格式和数据,否则很容易导致不匹配。 – alondono 2014-09-04 11:11:28

+0

您可以通过将两个列表翘曲成只允许同时添加值和格式的单个类(即formatZipper.AddField(string fmt,object data))来解决此问题。然后,您可以通过覆盖ToString()或提供某种方法或属性来运行for循环。这样做有更复杂的方法,但他们需要更多关于具体细节的知识。 – Benjamin 2014-09-04 17:02:11

+0

我很欣赏你的努力,但是它开始看起来有点复杂吗?无论如何,我喜欢你对这两个列表的想法。 – alondono 2014-09-05 01:12:57