最有效的Dictionary .ToString()格式化?
将Dictionary转换为格式化字符串的最有效方法是什么。
例如:
我的方法:
public string DictToString(Dictionary items, string format){ format = String.IsNullOrEmpty(format) ? "{0}='{1}' " : format; string itemString = ""; foreach(var item in items){ itemString = itemString + String.Format(format,item.Key,item.Value); } return itemString; }
有更好/更简洁/更有效的方式吗?
注意:字典最多有10个项目,如果存在另一个类似的“键值对”对象类型,我就不会使用它
另外,既然我无论如何都会返回字符串,那么通用版本会是什么样子?
我只是将你的版本重写为更通用的并使用StringBuilder
:
public string DictToString(IEnumerable> items, string format) { format = String.IsNullOrEmpty(format) ? "{0}='{1}' " : format; StringBuilder itemString = new StringBuilder(); foreach(var item in items) itemString.AppendFormat(format, item.Key, item.Value); return itemString.ToString(); }
public string DictToString(Dictionary items, string format) { format = String.IsNullOrEmpty(format) ? "{0}='{1}' " : format; return items.Aggregate(new StringBuilder(), (sb, kvp) => sb.AppendFormat(format, kvp.Key, kvp.Value)).ToString(); }
这种方法
public static string ToFormattedString(this IDictionary dic, string format, string separator) { return String.Join( !String.IsNullOrEmpty(separator) ? separator : " ", dic.Select(p => String.Format( !String.IsNullOrEmpty(format) ? format : "{0}='{1}'", p.Key, p.Value))); }
用下一个方法:
dic.ToFormattedString(null, null); // default format and separator
会转换
new Dictionary { { "a", "1" }, { "b", "2" } };
至
a='1' b='2'
要么
dic.ToFormattedString("{0}={1}", ", ")
至
a=1, b=2
不要忘记过载:
public static string ToFormattedString(this IDictionary dic) { return dic.ToFormattedString(null, null); }
您可以使用genericsTKey
/ TValue
因为任何对象都有ToString()
, String.Format()
将使用它。
至于IDictionary
是IEnumerable
你可以使用任何。 我更喜欢IDictionary以获得更多的代码表现力。
使用Linq和string.Join()(C#6.0)将字典格式化为一行:
Dictionary dictionary = new Dictionary() { ["key1"] = "value1", ["key2"] = "value2" }; string formatted = string.Join(", ", dictionary.Select(kv => $"{kv.Key}={kv.Value}")); // key1=value1, key2=value2
您可以像这样创建简单的扩展方法:
public static class DictionaryExtensions { public static string ToFormatString(this IDictionary dictionary, string format = null) { format = string.IsNullOrEmpty(format) ? "{0}='{1}'" : format; return string.Join(", ", dictionary.Select(kv => string.Format(format, kv.Key, kv.Value))); } }
使用扩展方法和默认参数,以及在{}中包装键/值对,可以轻松改进其他答案的版本:
public static string ItemsToString(this IEnumerable> items, string format = "{0}='{1}' ") { return items .Aggregate(new StringBuilder("{"), (sb, kvp) => sb.AppendFormat(format, kvp.Key, kvp.Value)) .Append('}') .ToString(); }
然后可以直接从字典/可枚举中调用该方法:
string s = myDict.ItemsToString()
我认为只有10个字符串,效率几乎不是问题,但也许你不想依赖它只有10个字符串。
字符串的连接在内存中创建一个新的String对象,因为String对象是不可变的。 这也表明其他String操作可能会创建新实例,如replace。 通常使用StringBuilder可以避免这种情况。
StringBuilder通过使用它运行的缓冲区来避免这种情况; 当StringBuilder的值与另一个String连接时,内容将被添加到缓冲区的末尾。
但是有一些警告,请看本段 :
性能考虑因素
[…]
String或StringBuilder对象的串联操作的性能取决于内存分配发生的频率。 字符串连接操作始终分配内存,而StringBuilder连接操作仅在StringBuilder对象缓冲区太小而无法容纳新数据时分配内存。 因此,如果连接固定数量的String对象,则String类更适合并置操作。 在这种情况下,编译器甚至可以将单个串联操作组合成单个操作。 如果连接任意数量的字符串,则StringBuilder对象最好用于连接操作; 例如,如果循环连接随机数量的用户输入字符串。
所以像这样的(人为的)案例可能不应该被StringBuilder取代:
string addressLine0 = Person.Street.Name + " " + Person.Street.Number + " Floor " + Person.Street.Floor;
…因为编译器可能能够将其减少到更有效的forms。 如果它对于更大的事物方案来说效率低,那么它也是值得商榷的。
根据Microsoft的建议,您可能希望使用StringBuilder(就像其他非常充分的答案所示)。
Gabe,如果你是通用的,那就是通用的:
public string DictToString(IDictionary items, string format) { format = String.IsNullOrEmpty(format) ? "{0}='{1}' " : format; StringBuilder itemString = new StringBuilder(); foreach(var item in items) itemString.AppendFormat(format, item.Key, item.Value); return itemString.ToString(); }