最近我花了一些时间来寻找一个棘手的行为,我做了类似的事情
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:没有警告,没有提示,加入名称部分被忽略了!
这似乎是编译器错误!!!
这不是一个问题,可能是其他人可以节省一些时间
答案 0 :(得分:2)
VS2012:没有警告,没有提示,加入名称部分被忽略了!这似乎是编译器错误!!!
不,实际上并非如此。这只是一个优先事项。 +
比??
更紧密。
你写完全合法的C# - 它只是没有按照你的预期去做。您的代码相当于:
return prefix ?? (string.Empty + string.Join(", ", names));
就个人而言,我会将代码重写为:
prefix = prefix ?? string.Empty;
return prefix + string.Join(", ", names);
编辑:正如Marc所说,你甚至不需要在这里做任何 - 因为null
在连接中最终是一个空字符串,所以你只需要:
return prefix + string.Join(", ", names);
我注意到,如果names
为空,则删除前缀或顺便提取null
- 是故意的吗?此外,我建议您使用""
或使用string.Empty
在 之间保持一致。我个人使用""
,但这是一个品味问题。尽管如此,一致性可以减少意外:)
请参阅C#5规范的7.3.1节,了解C#中各种运算符等的优先级列表。
答案 1 :(得分:1)
如果您执行以下操作,编译器也不会提供警告或提示:
var d = a + b * c;
当你的意思是:
var d = (a + b) * c;
在这两种情况下,这只是运算符优先级。这不是错误。
至于“名称部分被忽略” - 没有;如果prefix
为null
,则会对右侧进行评估(根据??
运算符的规则)。在您的特定场景中要实现的重要事情是没有括号,您的表达是有效的:
return prefix ?? (string.Empty + string.Join(", ", names));
就个人而言,我不建议学习运算符优先级规则:如果有疑问。 添加更多parantheses :
return (prefix ?? "") + string.Join(", ", names);
但是,使用null 的字符串连接会忽略null ,因此以下情况很好:
return prefix + string.Join(", ", names);