在 C# 中,为什么条件运算符不能隐式转换为可空类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/220250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 18:40:53  来源:igfitidea点击:

In C# why can't a conditional operator implicitly cast to a nullable type

c#conditional-operatornullable

提问by Tim Jarvis

I am curious as to why an implicit cast fails in...

我很好奇为什么隐式强制转换失败......

int? someValue = SomeCondition ? ResultOfSomeCalc() : null;

and why I have to perform an explicit cast instead

以及为什么我必须执行显式转换

int? someValue = SomeCondition ? ResultofSomeCalc() : (int?)null;

It seems to me that the compiler has all the information it need to make an implicit casting decision, no?

在我看来,编译器拥有做出隐式转换决定所需的所有信息,不是吗?

采纳答案by Brian Liang

The relevant section of the C# 3.0 spec is 7.13, the conditional operator:

C# 3.0 规范的相关部分是 7.13,条件运算符:

The second and third operands of the ?: operator control the type of the conditional expression. Let X and Y be the types of the second and third operands. Then,

?: 运算符的第二个和第三个操作数控制条件表达式的类型。设 X 和 Y 是第二个和第三个操作数的类型。然后,

If X and Y are the same type, then this is the type of the conditional Otherwise, if an implicit conversion (§6.1) exists from X to Y, but not from Y to X, then Y is the type of the conditional expression. Otherwise, if an implicit conversion (§6.1) exists from Y to X, but not from X to Y, then X is the type of the conditional expression. Otherwise, no expression type can be determined, and a compile-time error occurs.

如果 X 和 Y 的类型相同,则这是条件表达式的类型;否则,如果存在从 X 到 Y 的隐式转换(第 6.1 节),但不存在从 Y 到 X 的转换,则 Y 是条件表达式的类型。否则,如果存在从 Y 到 X 的隐式转换(第 6.1 节),但不存在从 X 到 Y 的隐式转换,则 X 是条件表达式的类型。否则,无法确定表达式类型,并发生编译时错误。

回答by TheSoftwareJedi

I also am annoyed that it can't infer the type based on the assignment, especially when it's a value type. There are reasons though when you get into object heirarchies.

我也很恼火,它无法根据赋值推断类型,尤其是当它是值类型时。但是,当您进入对象层次结构时是有原因的。

If "ResultOfSomeCalc()" returned a "int?", then this would work. C# needs to figure out the type regardless of what is to the left of the assignment. So you are telling it that you'll return a null or an int - and the logic in the compiler doesn't exist to have it substitute a Nullable as a common denominator.

如果“ResultOfSomeCalc()”返回一个“int?”,那么这将起作用。C# 需要弄清楚类型,而不管赋值的左边是什么。所以你告诉它你将返回一个 null 或一个 int - 并且编译器中的逻辑不存在让它替代 Nullable 作为公分母。

Notice that these variants DO work, and it may help you understand:

请注意,这些变体确实有效,它可能会帮助您理解:

object someValue = true ? new Nullable<int>(ResultOfSomeCalc()) : null;

object someValue = true ? (int?)ResultOfSomeCalc() : null;

Hope this helps.

希望这可以帮助。

回答by harpo

If your function ResultofSomeCalc() returns int? then this will work.

如果您的函数 ResultofSomeCalc() 返回 int?那么这将起作用。

If your function returns int, then the compiler issues the warning: Type of conditional expression cannot be determined because there is no implicit conversion between 'int' and ''
I'm guessing that is what you are seeing. Both expressions in the conditional operator "?:" must have the same type, or must be convertible to the same type via an implicit cast.

如果您的函数返回 int,则编译器会发出警告:无法确定条件表达式的类型,因为 'int' 和 '' 之间没有隐式转换,
我猜这就是您所看到的。条件运算符“?:”中的两个表达式必须具有相同的类型,或者必须通过隐式强制转换可转换为相同的类型。

Change the return type of ResultOfSomeCalc to int?, or you will need to have the cast on the null expression.

将 ResultOfSomeCalc 的返回类型更改为 int?,否则您将需要对空表达式进行强制转换。

回答by Mr. Putty

It sure seems like this is something the compiler should be able to figure out for itself, but there is one other way to do this, using the default keyword. It might be the tiniest bit less ugly than the cast:

看起来这是编译器应该能够自己弄清楚的事情,但是还有另一种方法可以做到这一点,使用 default 关键字。它可能是最不比演员更丑的一点:

int? someValue = SomeCondition ? ResultofSomeCalc() : default(int?);

This use of default doesn't seem to be well documented, but is does work. At least it keeps you from having to litter your code with magic values (I contend that null/zero/false/etc. are indeed magic values).

这种默认的使用似乎没有很好的记录,但确实有效。至少它使您不必用魔法值乱扔代码(我认为 null/zero/false/etc. 确实是魔法值)。

回答by Abdus Salam Azad

Make your function ResultOfSomeCalc()'s return type as nullabel int like (int?)
int? someValue =(int?) SomeCondition ? ResultofSomeCalc() : (int?)null;

使您的函数 ResultOfSomeCalc() 的返回类型为 nullabel int like (int?)
int? someValue =(int?) SomeCondition ? ResultofSomeCalc() : (int?)null;