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

Console.WriteLine(tmp);

这将打印出接近于:'a ('.

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

4

7 回答 7

8

空合并运算符 ??的优先级低于+运算符,因此您的代码等于

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

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

于 2013-07-09T12:57:58.570 回答
6

首先,您应该始终假设这是您的,而不是编译器的错;select没有坏。你真的认为??操作符的 Visual Studio 2010 实现没有经过实战测试吗?当您遇到与您的期望不符的事情时,请检查您的期望。拿出手册,并确保完全理解假设会发生什么。在这种情况下,请打开语言规范。

如果您继续阅读规范的第 1.4 节,您将看到一个将运算符分组为优先级分组的表格;你也可以在网上找到它。特别是,空合并运算符??位于底部附近,仅高于低条件三元运算符和赋值和=>。它低于加法运算符。因此,您的陈述

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

被编译器视为

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

我不会完全迂腐,不会在第一个加法表达式1中加上括号。由于该语句中表达式的左侧永远不会为空,因此它当然总是"a("(或"a("+date.ToString()date.HasValue为真时)分配给tmp.

要点对应该发生的事情有错误的期望,应该根据手册进行验证。

如果我放在date ?? "blablabla"括号中,则会在错误中加下划线。

当然是。您甚至阅读了错误消息吗?它可能会告诉您,您不能??在 aDateTime?和 a上执行操作,因为在任何一个方向string之间都没有隐式转换。这也包含在语言规范中;见第 7.13 节。您必须阅读此消息并做出回应。要获得与您要表达的内容在语义上等效的内容必须求助于条件三元运算符:DateTime?string

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

然后将整个内容放在括号中,因为条件三元运算符的优先级很低

最后,我发现您的代码的正确括号版本相当丑陋,阅读起来并不有趣,而且维护起来可能也不愉快。简单点,拜托:

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

现在很清楚正在发生什么以及将要发生什么。我不需要思考就能理解它。把你的想法留到你将遇到的困难问题上。

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

于 2013-07-09T13:04:43.153 回答
3

这里只是另一个版本:

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

我真的很喜欢string.Format而不是串联。

于 2013-07-09T13:01:09.987 回答
2

"blablabla"不是日期,所以你不能使用 is 来设置一个date?.


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

相当于

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

这就是你a(的来源。


然而

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

或类似的应该工作。

于 2013-07-09T12:55:57.750 回答
1

来自C# 语言规范 §1.4

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

它说加法运算符的优先级高于空合并运算符。

因此,+具有更高的优先级??,这就是"blablabla" + ")"表达式首先起作用的原因。

由于dateis null,该语句的工作方式如下;

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

通常结果将是a(

于 2013-07-09T12:58:13.227 回答
0

这不是空合并运算符的错误。

它的运算符优先级

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

是相同的:

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

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

于 2013-07-09T12:57:07.313 回答
0

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

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

应该管用。

于 2013-07-09T12:55:06.127 回答