这是Visual Studio 2010编译器中的错误吗?

时间:2013-07-09 12:52:14

标签: c# .net visual-studio-2010

DateTime? date = null;
string tmp = "a" + "(" + date ?? "blablabla" + ")";

Console.WriteLine(tmp);

这将打印接近'a ('

的内容

这是null-coalescing operator的错误吗? 如果我将date ?? "blablabla"括在括号中,则会将其加下划线为错误。

7 个答案:

答案 0 :(得分:8)

Null-coalescing operator ??的优先级低于+运算符,因此您的代码等于

string tmp = ("a" + "(" + date) ?? ("blablabla" + ")");

由于+操作中的所有内容都使用字符串生成一个字符串(通过在所有非字符串操作数上调用.ToString()),因此您的代码将始终生成"a("字符串。

答案 1 :(得分:5)

首先,你应该always assume it's your fault,而不是编译器的错; select isn't broken。您是否真的认为??运算符的Visual Studio 2010实现尚未经过战斗测试?当您遇到与您的期望不符的事情时,请检查您的期望。获取手册,确保完全理解 假设发生的事情。在这种情况下,请打开语言规范。

如果继续执行specification的§1.4,您将看到一个将运算符分组为优先级分组的表;你也可以找到它online。特别是,空合并运算符??靠近 bottom ,仅在低条件三元运算符和赋值和=>之上。 低于添加剂运算符。因此,您的声明

string tmp = "a" + "(" + date ?? "blablabla" + ")";

被编译器视为

string tmp = (("a" + "(" + date) ?? ("blablabla" + ")"));

我不会完全迂腐,将第一个加法表达式 1 括起来。由于该语句中表达式的左侧是从不 null,当然总是分配"a("(或"a(" + {当date.ToString()为真时{1}} date.HasValue。{/ p>

点是对于应该根据手册进行验证应该发生什么的错误预期。< / p>

  

如果我将tmp放在括号中,则会将其加下划线为错误。

当然是。你有没看过错误信息?它可能会告诉您,date ?? "blablabla"??上无法DateTime?,因为stringDateTime?之间在任何方向都没有隐式转换。这也包含在语言规范中;见§7.13。您必须阅读此消息并回复。要获得语义等同于尝试表达的内容,您将不得不求助于条件三元运算符:

string

然后将整个事物包装在括号中,因为条件三元运算符的非常低优先级。

最后,我发现代码的正确括号版本相当丑陋,阅读起来并不好玩,而且可能无法维护。请简单一点,请:

date.HasValue ? date.ToString() : "blablabla"

现在所以清楚发生了什么以及将会发生什么。我不必来理解它。保存您对遇到的难题的想法。

1 :小心。在尝试正确计算出先评估的内容之前,我们需要添加一个方法调用var tmp = String.Format("a({0})", date.HasValue ? date.ToString() : "blablabla"); (具有最高优先级)。

答案 2 :(得分:3)

这里只是另一个版本:

DateTime? date = null;
string tmp = string.Format("a({0})", 
                           date.HasValue ? date.ToString() : "blablabla");

我真的很喜欢string.Format而不是连接。

答案 3 :(得分:2)

"blablabla"不是日期,因此您无法使用is来设置date?


string tmp = "a" + "(" + date ?? "blablabla" + ")";

相当于

string tmp = ("a" + "(" + date) ?? ("blablabla" + ")");

这是a(来自的地方。


然而

string tmp = "a" + "(" + (date ?? DateTime.Now) + ")";

或类似的应该有效。

答案 4 :(得分:1)

来自C# Language Specification §1.4

  

下表总结了C#的运营商,列出了运营商   按优先顺序从最高到最低的类别。运营商   同一类别具有相同的优先权。

它表示Additive operators的优先级高于空合并运算符。

因此,+的优先级高于??,这就是"blablabla" + ")"表达式首先运作的原因。

由于datenull,因此声明的作用类似于

string tmp = "a" + "(" + null;

通常结果为a(

答案 5 :(得分:0)

这很可能是因为date不是字符串,而??运算符无法确定date"blablabla"的公共基本类型。试试(date.ToString() ?? "blablabla")。但这不能满足您的需求,因为date.ToString()永远不会是null

string tmp = "a" + "(" + (date ?? DateTime.Now) + ")";

应该有用。

答案 6 :(得分:0)

这不是null-coalescing运算符的错误。

这是operator precedence

"a" + "(" + date ?? "blablabla" + ")"

与:

相同
("a" + "(" + date.ToString() ) ?? ( "blablabla" + ")" )

("a" + "(" + date.ToString() )不为空。