为什么 null 需要在这里进行显式类型转换?

发布于 2024-08-28 06:39:46 字数 352 浏览 8 评论 0原文

以下代码无法编译:

//int a = ...
int? b = (int?) (a != 0 ? a : null);

为了编译,需要将其更改为

int? b = (a != 0 ? a : (int?) null);

由于 b = nullb = a 都是合法的,所以这没有意义大部头书。

为什么我们必须将 null 转换为 int? 为什么我们不能简单地为整个表达式提供显式类型转换(我知道这在其他表达式中是可能的)例)?

The following code does not compile:

//int a = ...
int? b = (int?) (a != 0 ? a : null);

In order to compile, it needs to be changed to

int? b = (a != 0 ? a : (int?) null);

Since both b = null and b = a are legal, this doesn't make sense to me.

Why do we have to cast the null into an int? and why can't we simply provide an explicit type cast for the whole expression (which I know is possible in other cases)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

青瓷清茶倾城歌 2024-09-04 06:39:46

来自 C# 语言规范第 7.13 章:

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

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

在您的情况下,没有从 int 到 null 的隐式转换,也没有相反的转换。你的强制转换解决了问题,int可以转换为int吗?

From chapter 7.13 of the C# Language Specification:

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,

  • If X and Y are the same type, then this is the type of the conditional expression.
  • 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.

In your case, there is no implicit conversion from int to null nor the other way around. Your cast solves the problem, int is convertible to int?

咽泪装欢 2024-09-04 06:39:46

?: 运算符的两个替代项必须是同一类型。
否则,编译器无法推断出整个条件表达式的类型。

null 不是 int,因此您需要向编译器提示结果类型是 int?


编辑:正如其他人指出的那样,这两种类型不需要相同,但其中一种类型应该可以转换为另一种类型(另一种类型将是结果类型)。有关更多详细信息,请参阅规范

The both alternatives of ?: operator must be of the same type.
Otherwise, the compiler cannot deduce the type of the whole conditional expression.

null is not an int, so you need to give a hint to the compiler that the resulting type is int?.


Edit: as the others pointed out, the two types don't need to be the same, but one of them should be castable to another (that another one will be the result type). See specs for more details.

随波逐流 2024-09-04 06:39:46

如果使用 default(int?) 而不是 null,则可以避免强制转换。

int a = 42;
int? b = (a != 0 ? a : default(int?));

You can save yourself from casting if you use default(int?) instead of null.

int a = 42;
int? b = (a != 0 ? a : default(int?));
杀手六號 2024-09-04 06:39:46

这是因为当你使用这种表示法时,两个成员必须是相同的类型,所以你必须明确地说“这个成员是一个 int?”。

清楚了吗?

it's because when you use that kind of notation, both member must be of the same type, so you have to explicitly say "this member is a int?".

is it clear ?

遗心遗梦遗幸福 2024-09-04 06:39:46

当您将条件运算符与不同类型的操作数一起使用时,编译器将检查其中一种类型是否可以隐式转换为另一种类型。

如果这两种类型都不能隐式转换为另一种类型,则会给出错误,即使存在它们都可以隐式转换为的第三种类型。编译器不会同时在两侧插入隐式转换。

在您的情况下,intnull 都需要隐式转换才能成为 int?,因此它不起作用。
您需要更改代码,以便一侧是 int?,另一侧可以隐式转换为 int?。最简单的方法是将 null 替换为 new int?(),如下所示:

int? b = (a != 0 ? a : new int?());

这只需要一次隐式转换(intint?)。

When you use the conditional operator with operands of different types, the compiler will check whether one of the types can be implicitly converted to the other type.

If neither type can be implicitly converted to the other one, it will give an error, even if there is a third type that they can both implicitly convert to. The compiler will not insert an implicit conversion on both sides at once.

In your case, both int and null requires implicit conversions to become int?, so it doesn't work.
You need to change your code so that one side is an int? and the other side can be implicitly converted to int?. The simplested way to do this is to replace null with new int?(), like this:

int? b = (a != 0 ? a : new int?());

This only requires one implicit conversion (int to int?).

秋叶绚丽 2024-09-04 06:39:46

这几乎是我关于条件运算符的一个问题的重复。它不是 null,它实际上是 :

那里接受的答案非常好,来自 C# 编译器团队的 Eric Lippert。

This is pretty much a duplicate of one of my questions, regarding the conditional operator. It's not the null, it really is the :.

The answer accepted there is pretty good, from none other than Eric Lippert, who is on the C# compiler team.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文