2014-02-12 30 views
1

我想写一个扩展方法,这将有助于快速查看IEnumerable<KeyValuePair<object, object>>的内容。我在正确书写我的签名时遇到了一些麻烦。下面的代码适用于字符串,但我希望能够在任何通用类型的KeyValuePair上使用它。如果将它更改为接受IEnumerable<KeyValuePair<object, object>>然后尝试在Dictionary<string,string>类型上调用它类型我得到一个编译器错误“实例参数:无法从'System.Collections.Generic.Dictionary'转换为'System.Collections.Generic.IEnumerable>'”,尽管Dictionary<TKey, TValue>实现接口IEnumerable<KeyValuePair<TKey, TValue>>函数接受通用的IEnumerable的KeyValuePair

public static string ToHumanReadableString(this IEnumerable<KeyValuePair<string, string>> dictionary) 
{ 
    if (dictionary.IsNull()) 
    { 
    return "{null}"; 
    } 
    StringBuilder sb = new StringBuilder(); 
    foreach (KeyValuePair<string, string> kvp in dictionary) 
    { 
    if (!kvp.Value.IsNull()) 
    { 
     sb.AppendLineAndFormat("{0}={1}", kvp.Key.ToString(), kvp.Value.ToString()); 
    } 
    else 
    { 
     sb.AppendLineAndFormat("{0}={null}", kvp.Key.ToString()); 
    } 
    } 
    return sb.ToString(); 
} 
+1

为什么不让你的方法在TKey和TValue上是通用的? – Magus

+0

你可以发布你的代码吗?我尝试将签名更改为公共静态字符串ToHumanReadableString(此IEnumerable >字典)',但它说“无法找到类型或命名空间'TKey'” – mason

+0

您必须将尖括号在parens之前的tkey和tvalue。 – Magus

回答

2

使函数通用的,就像这样:

public static string ToHumanReadableString<TKey, TValue>(
    this IEnumerable<KeyValuePair<TKey, TValue>> dictionary) 
    where TKey : class 
    where TValue : class 
{ 
    if (dictionary.IsNull()) 
    { 
     return "{null}"; 
    } 
    StringBuilder sb = new StringBuilder(); 
    foreach (var kvp in dictionary) 
    { 
     if (!kvp.Value.IsNull()) 
     { 
      sb.AppendLineAndFormat("{0}={1}", kvp.Key.ToString(), kvp.Value.ToString()); 
     } 
     else 
     { 
      sb.AppendLineAndFormat("{0}={null}", kvp.Key.ToString()); 
     } 
    } 
    return sb.ToString(); 
} 

请注意,我还添加constraintsTKeyTValue类型必须课,否则你的null检查就没有太大的意义。

+0

不确定在哪里定义了IsNull(),但即使对于值类型,空检查也不应该是一个问题(它当然总是为false),所以对'class'的约束不应该是必要的(并且会阻止它起作用于数字类型) –

+0

@DStanley大概这是OP写的一个扩展方法。所以这是不必要的。我想提供关于约束的注释,因为它似乎像OP尝试将它与类一起使用,但是,如果OP需要将它与结构一起使用,则约束可能会被删除。 –

+0

@DStanley'IsNull()'和'AppendLineAndFormat()'是我写的或在线发现的扩展方法。他们对这个问题并不重要。 – mason

4

可以使通用的方法(在注释附注变化):

public static string ToHumanReadableString<TKey, TValue>(
    this IEnumerable<KeyValuePair<TKey, TValue>> dictionary) 
{ 
    if (dictionary == null) 
    { 
     return "{null}"; 
    } 
    StringBuilder sb = new StringBuilder(); 
    foreach (var kvp in dictionary) // note change 
    { 
     if (kvp.Value == null) // note change 
     { 
      sb.AppendLineAndFormat("{0}={1}", kvp.Key.ToString(), kvp.Value.ToString()); 
     } 
     else 
     { 
      sb.AppendLineAndFormat("{0}={null}", kvp.Key.ToString()); 
     } 
    } 
    return sb.ToString(); 
} 

请注意,我还格式化你的括号使用更标准的缩进。

+0

他的缩进很好,只是标签。 SO不喜欢它们。 – Magus

+0

我使用标签是,但我也喜欢块样式缩进,。 – mason

相关问题