0

最近我花了一些时间发现一个棘手的行为,我做了这样的事情

public static string GetPrefixedNameList(string[] names, string prefix = null)
{
    if (names == null || names.Length == 0)
        return "";
    return prefix ?? string.Empty + string.Join(", ", names);
}

很容易,我问,但我总是只得到前缀或结果为空字符串,但从来没有加入名单

让它正常工作: 当它是一个中间结果时,总是用括号括起来“??评估部分”!

return (prefix ?? string.Empty) + string.Join(", ", names);

VS2012:没有警告,没有提示,加入名称部分被忽略了!!!这似乎是一个编译器错误!!!

这不是一个真正的问题,也许其他人可以节省一些时间

4

2 回答 2

2

VS2012:没有警告,没有提示,加入名称部分被忽略了!!!这似乎是一个编译器错误!!!

不,真的不是。这只是一个优先事项。+比 绑定得更紧??

您已经编写了完全合法的 C# - 它只是没有按照您的预期进行。您的代码相当于:

return prefix ?? (string.Empty + string.Join(", ", names));

我个人会将代码重写为:

prefix = prefix ?? string.Empty;
return prefix + string.Join(", ", names);

编辑:正如马克所说,你甚至不需要在这里做任何事情- 因为null在连接中最终是一个空字符串,所以你只需要:

return prefix + string.Join(", ", names);

我注意到你删除了前缀 ifnames是空的,或者null,顺便说一句 - 这是故意的吗?另外,我建议您应该在usingusing"" 之间string.Empty保持一致。我个人使用"",但这是一个品味问题。一致性虽然减少了惊喜:)

有关 C# 中各种运算符等的优先级列表,请参阅 C# 5 规范的第 7.3.1 节。

于 2013-06-12T06:59:29.130 回答
1

如果您这样做,编译器也不会提供警告或提示:

var d = a + b * c;

当你的意思是:

var d = (a + b) * c;

在这两种情况下,这只是运算符优先级。这不是错误。

至于“名称部分被简单地忽略了” - 不;如果prefixnull,则将评估右侧(根据??操作员的规则)。在您的特定场景中要实现的重要一点是,如果没有括号,您的表达式是有效的:

return prefix ?? (string.Empty + string.Join(", ", names));

就个人而言,我不建议学习运算符优先规则:如果有疑问。添加更多括号

return (prefix ?? "") + string.Join(", ", names);

但是,与 null 的字符串连接会忽略 null,因此可以使用以下方法:

return prefix + string.Join(", ", names);
于 2013-06-12T07:01:44.067 回答