如何优雅地将IDictionary<string, object>转换为IDictionary<string, string>?

3

我有一个方法,但对它不太满意,你能否请指教如何更好地实现。

public Foo WithBar(IDictionary<string, object> parameters) {
    var strStrDict = new Dictionary<string, string>(parameters.Count);
    foreach(var pair in parameters)
    {
        strStrDict.Add(pair.Key, pair.Value != null ? pair.Value.ToString() : (string)null);
    }      
    // Call overload which takes IDictionary<string, string>  
    return this.WithBar(strStrDict);
}

这段代码可以工作,但我相信有一种更好的Linq方式可以完成这个任务,而我可能还没有想到。


2
你应该对自己的方法感到不满的原因之一:它已经失效了!pair.Value == null ? pair.Value.ToString() : (string)null会很好地爆炸。 - Anthony Pegram
谢谢Anthony,我提出了问题并开始编写单元测试。所以刚刚找到了答案。 - David Waters
感谢大家的快速和友好的回答。 - David Waters
3个回答

8
parameters.ToDictionary(k=>k.Key, v=>v.Value!=null?v.Value.ToString():(string)null);

1
那个结构被称为 as ;) - Dykam
2
@dykam,绝对不是这样的。as执行引用转换,如果对象不是字符串,则返回null。ToString返回对象的字符串表示形式,这是完全不同的东西... - Thomas Levesque
3
从技术上讲,(string)null并不是必需的。在表达式condition ? obj.ToString() : null;中,编译器已经有足够的信息来确定表达式的类型为字符串。 - Anthony Pegram
@Thomas Levesque,我假设他有一个Dict<string, object>,其中所有的键都是字符串,所以他只需要进行强制转换。但这仍然不能使as等价于你的代码。 - Dykam

4
parameters.ToDictionary(k => k.Key, v => Convert.ToString(v.Value))

Convert.ToString()在空值(null-values)的情况下返回null,这是您所期望的。

更新:

Convert.ToString(object)返回String.Empty,但Convert.ToString(string)返回null。不幸的是,这不是您需要的。在我看来,这是一种奇怪的定义 :-/


3
Convert.ToString(null) 返回 String.Empty。这在我的单元测试中失败了 :) - David Waters
有趣的转折。在 LinqPad 中(即将在 VS 中测试),Convert.ToString(null) 返回 null,但是 object obj = null; Convert.ToString(obj) 返回空字符串。 - Anthony Pegram
@David Waters 我明白了 :) 我显然是针对错误的 Convert.ToString 进行测试的(请参见更新的答案)。@Anthony Pegram 是的,它会选择最具体的重载。 - Lasse Espeholt
是的,文档支持您的编辑。当显式传递 null 时,重载解析会选择返回未更改的字符串的 string 版本(因此得到 null)。由于 null 可用于对象和字符串,重载解析会选择更具体的类型,即字符串。编辑:或者就像您刚才说的那样。 - Anthony Pegram

-1
parameters.ToDictionary(p => p.Key, p => p.Value.ToString())  // out of my head

您将在空值上获得异常。 - Lasse Espeholt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接