C# 这是VisualStudio2010编译器中的错误吗?
这将打印接近:C# 这是VisualStudio2010编译器中的错误吗?,c#,.net,visual-studio-2010,C#,.net,Visual Studio 2010,这将打印接近:'a(')的内容 这是空合并运算符的错误吗? 如果我把date??“blablabla”放在括号中,它会被下划线为错误。这很可能是因为date不是字符串,?操作符无法确定date和“blablabla”的公共基类型。请尝试(date.ToString()??“blablablablablablablablabla>)。但这也不能满足您的需要,因为date.ToString()永远不会为null DateTime? date = null; string tmp = "a" + "(
'a('
)的内容
这是空合并运算符的错误吗?
如果我把date??“blablabla”
放在括号中,它会被下划线为错误。这很可能是因为date
不是字符串,?
操作符无法确定date
和“blablabla”
的公共基类型。请尝试(date.ToString()??“blablablablablablablablabla>)
。但这也不能满足您的需要,因为date.ToString()
永远不会为null
DateTime? date = null;
string tmp = "a" + "(" + date ?? "blablabla" + ")";
Console.WriteLine(tmp);
应该有效。“blabla”
不是日期,所以不能使用is设置日期
相当于
string tmp = "a" + "(" + date ?? "blablabla" + ")";
这就是你的a(
来自哪里
然而
string tmp = ("a" + "(" + date) ?? ("blablabla" + ")");
或者类似的方法应该可以工作。这不是空合并运算符的错误
它是:
同:
"a" + "(" + date ?? "blablabla" + ")"
和(“+”(“+date.ToString())
不为空。??
的优先级低于+
运算符,因此您的代码等于
("a" + "(" + date.ToString() ) ?? ( "blablabla" + ")" )
由于使用字符串的+
操作中的所有内容都会生成一个字符串(通过对所有非字符串操作数调用.ToString()
),因此代码将始终从
下表总结了C#的运算符,列出了该运算符
按从高到低的优先级顺序排列的类别。中的运算符
同一类别具有同等优先权
它说它的优先级高于空合并运算符
所以,它的优先级高于,这就是为什么“blabla”+”
表达式首先工作的原因
由于date
为null
,因此该语句的工作原理如下:
string tmp = ("a" + "(" + date) ?? ("blablabla" + ")");
通常结果是a(
这里是另一个版本:
string tmp = "a" + "(" + null;
我真的很喜欢字符串。格式化而不是串接。首先,你应该这样做,而不是编译器的错。??
操作符的Visual Studio 2010实现没有经过战斗测试吗?当你遇到与你的期望不符的东西时,检查你的期望。退出ma一年一次,并确保您完全理解假设发生的情况。在这种情况下,请打开语言规范
如果继续执行的§1.4,您将看到一个表,该表将运算符分组为优先分组;您也可以找到它。特别是,空合并运算符?
位于底部附近,仅位于低级条件三元运算符和赋值的上方和=>
的下方。它位于加法运算符的下方。因此,您的语句
被编译器视为
string tmp = "a" + "(" + date ?? "blablabla" + ")";
我不会完全学究式,也不会将第一个加法表达式1括起来。因为该语句中表达式的左侧永远不会为null,当然它总是将“a(“
”(或“a”(“
+日期.ToString()
当日期.HasValue
为true时)赋值给tmp
主要的一点是,对于应该发生的事情,您有一个错误的期望,您应该对照手册进行验证
如果我把date???“blabla”
放在括号中,则下划线为error
当然是这样。您读过错误消息吗?它可能会告诉您不能对日期时间?
和字符串
执行?
,因为日期时间?
和字符串
之间在两个方向上都没有隐式转换。这也包含在语言规范中;请参见§7.13。您必须阅读此消息并作出响应。要获得与您试图表达的内容语义等价的内容,您必须使用条件三元运算符:
string tmp = (("a" + "(" + date) ?? ("blablabla" + ")"));
然后用括号括起来,因为条件三元运算符的优先级很低
最后,我发现正确插入括号的代码版本非常难看,阅读起来不有趣,维护起来可能也不愉快。请简单一点:
date.HasValue ? date.ToString() : "blablabla"
现在已经很清楚发生了什么,将要发生什么。我不需要思考就能理解它。把你的想法留给你将遇到的困难问题吧
1:小心。我们需要添加对date.ToString
(具有最高优先级)的方法调用,然后才能尝试正确计算出首先要计算的内容。不要用大括号括住date??“blablablabla”
,但要用括号括起来,并让我们知道这是否改变了什么。“这是编译器错误吗?”99.99%的情况下答案是否定的。我只发现过一个编译器错误,那是20年前的事了。这一点很容易确认,因为调用在特定编译器的一个版本中编译成了故障代码,但表现不同(而且正确)在之前和后续版本中。情况并非如此。另外,如果date
为null
,并且您尝试在其上调用ToString()
,您将得到NullReferenceException
(嗯,这可能只适用于作为引用类型的可空类型,DateTime
是一个ValueType,因此它的可空类型应该是值类型nullable
,而不是基于类的类型,所以这可能行吗?。@您的建议是正确的-((DateTime?)null)。ToString()执行时没有错误。优先于优先权“,我想说。还需要注意的是,与null组合的非null字符串会产生非null字符串,而不是错误或null,因此,+date
实际上是不可操作的。我也这样做了;除了最简单的表达式外,它会产生更可读和可维护的代码。这个答案比选择的答案要好得多。
string tmp = "a" + "(" + date ?? "blablabla" + ")";
string tmp = (("a" + "(" + date) ?? ("blablabla" + ")"));
date.HasValue ? date.ToString() : "blablabla"
var tmp = String.Format("a({0})",
date.HasValue ? date.ToString() : "blablabla");