最有效的Dictionary <k,v> .ToString()格式化?</k,v>

时间:2010-09-03 19:46:44

标签: c# .net dictionary type-conversion tostring

将Dictionary转换为格式化字符串的最有效方法是什么。

e.g:

我的方法:

public string DictToString(Dictionary<string, string> 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个项目,我不会使用它

另外,既然我无论如何都会返回字符串,那么通用版本会是什么样的呢?

7 个答案:

答案 0 :(得分:22)

我刚刚将您的版本改写为更通用,并使用StringBuilder

public string DictToString<T, V>(IEnumerable<KeyValuePair<T, V>> 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(); 
}

答案 1 :(得分:16)

public string DictToString<TKey, TValue>(Dictionary<TKey, TValue> 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();
}

答案 2 :(得分:9)

此方法

public static string ToFormattedString<TKey, TValue>(this IDictionary<TKey, TValue> 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<string, string>
{
    { "a", "1" },
    { "b", "2" }
};

a='1' b='2'

dic.ToFormattedString("{0}={1}", ", ")

a=1, b=2

不要忘记过载:

public static string ToFormattedString<TKey, TValue>(this IDictionary<TKey, TValue> dic)
{
    return dic.ToFormattedString(null, null);
}

您可以使用通用TKey / TValue,因为任何对象都有ToString() String.Format()将使用。

至于IDictionary<TKey, TValue>IEnumerable<KeyValuePair<TKey, TValue>>,你可以使用任何。我更喜欢IDictionary以获得更多的代码表达能力。

答案 3 :(得分:3)

使用Linq和string.Join()(C#6.0)在一行中格式化字典:

Dictionary<string, string> dictionary = new Dictionary<string, string>()
{
    ["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<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, string format = null)
    {
        format = string.IsNullOrEmpty(format) ? "{0}='{1}'" : format;
        return string.Join(", ", dictionary.Select(kv => string.Format(format, kv.Key, kv.Value)));
    }
}

答案 4 :(得分:2)

使用扩展方法和默认参数轻松改进其他答案的版本,并在{}中包装键/值对:

public static string ItemsToString<TKey, TValue>(this IEnumerable<KeyValuePair<TKey, TValue>> items, string format = "{0}='{1}' ")
{
    return items
        .Aggregate(new StringBuilder("{"), (sb, kvp) => sb.AppendFormat(format, kvp.Key, kvp.Value))
        .Append('}')
        .ToString();
}

然后可以直接从字典/ enumerable中调用该方法:

string s = myDict.ItemsToString()

答案 5 :(得分:1)

我认为只有10个字符串,效率几乎不是问题,但也许你不想仅仅依赖于10个字符串。

字符串的连接在内存中创建一个新的String对象,因为String对象是不可变的。这也表明其他String操作可能会创建新实例,例如replace。通常使用StringBuilder可以避免这种情况。

StringBuilder通过使用它运行的缓冲区来避免这种情况;当StringBuilder的值与另一个String连接时,内容将被添加到缓冲区的末尾。

但有一些警告,请参阅this paragraph

  

效果考虑因素

     

[...]

     

串联的表现   String或的操作   StringBuilder对象取决于方式   通常会发生内存分配。一个   字符串连接操作始终   分配内存,而a   StringBuilder连接操作   只有分配内存   StringBuilder对象缓冲区也是如此   小到容纳新数据。   因此,String类是   最好是串联   操作如果是固定数量的String   对象是连接的。在那里面   个案,个别串联   甚至可以将操作合并到一起   编译器的单个操作。一个   StringBuilder对象更适合   一个连接操作,如果一个   任意数量的字符串   级联;例如,如果一个循环   连接随机数   用户输入字符串。

因此,像这样的(人为的)案例可能不应该被StringBuilder取代:

string addressLine0 = Person.Street.Name +  " " + Person.Street.Number + " Floor " + Person.Street.Floor;

...因为编译器可能能够将其减少到更有效的形式。如果在更大的方案中它足够低效,那么它也是值得商榷的。

根据Microsoft的建议,您可能希望使用StringBuilder(就像其他非常适当的答案所示。)

答案 6 :(得分:0)

Gabe,如果你是通用的,那就是通用的:

public string DictToString<T>(IDictionary<string, T> 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();  
}