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

kul*_*_mi 5 .net c# visual-studio-2010

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

Console.WriteLine(tmp);
Run Code Online (Sandbox Code Playgroud)

这将打印接近的东西:'a ('.

这是一个错误null-coalescing operator吗?如果我放入date ?? "blablabla"括号,则将其加下划线为错误.

Age*_*ire 8

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

string tmp = ("a" + "(" + date) ?? ("blablabla" + ")");
Run Code Online (Sandbox Code Playgroud)

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


jas*_*son 6

首先,你应该总是认为这是你的,而不是编译器的错; select没有打破.你真的认为??运营商的Visual Studio 2010实现还没有经过战斗测试吗?当您遇到与您的期望不符的事情时,请检查您的期望.走出手册,并确保明白究竟什么是假设发生.在这种情况下,请打开语言规范.

如果继续执行规范的 §1.4 ,您将看到一个将运算符分组为优先级分组的表.你也可以在网上找到它.特别是,空合并运算符??靠近底部,仅在低条件三元运算符和赋值之上=>.它低于添加剂操作员.因此,你的陈述

string tmp = "a" + "(" + date ?? "blablabla" + ")";
Run Code Online (Sandbox Code Playgroud)

被编译器视为

string tmp = (("a" + "(" + date) ?? ("blablabla" + ")"));
Run Code Online (Sandbox Code Playgroud)

我不会完全迂腐,也会将第一个加法表达式括起来1.由于在声明中表达的左手侧是从来没有空,当然它总是分配"a("(或"a("+ date.ToString()date.HasValue为true) tmp.

主要的一点是,有一个不正确的期待,什么应该发生的是,你应该对手册已经验证.

如果我放入date ?? "blablabla"括号,则将其加下划线为错误.

当然如此.你有没看过错误信息?它可能告诉您,您不能??对a DateTime?和a 执行操作,string因为在任一方向之间DateTime?和之间都没有隐式转换string.这也包含在语言规范中; 见§7.13.您必须阅读此消息并回复它.为了获得在语义上等同于你想要表达的东西,你将不得不求助于条件三元运算符:

date.HasValue ? date.ToString() : "blablabla"
Run Code Online (Sandbox Code Playgroud)

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

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

var tmp = String.Format("a({0})", 
                       date.HasValue ? date.ToString() : "blablabla");
Run Code Online (Sandbox Code Playgroud)

现在,它是如此清楚是怎么回事,什么事情发生.我不必考虑理解它.保存您对遇到的难题的想法.

1:小心.date.ToString在尝试正确计算出首先计算的内容之前,我们需要添加方法调用(具有最高优先级).

  • 这个答案比选择的答案要好得多. (2认同)