[英]C# type inference (“var”) assignment from '??' null-coalescing operator
I've read many of the SO questions on the null coalescing ??
我已经阅读了关于空合并的许多SO问题??
operator but none of them seem to address the following specific issue, which concerns neither nullability ( here ), operator precedence ( here and here ) nor especially implicit conversion ( here , here , here and here ). 运算符但它们似乎都没有解决以下特定问题,它既不涉及可空性 ( 此处 ), 运算符优先级 ( 此处和此处 ),也不涉及隐式转换 ( 此处 , 此处 , 此处和此处 )。 I've also read the .NET docs (more here ) and tried to read the offical spec , but sadly all to no avail. 我也阅读了.NET文档 (更多这里 )并尝试阅读官方规范 ,但遗憾的是都无济于事。
So here goes. 所以这里。 The only difference between the following two lines is the use of var
for type inference in the second, versus explicit type Random
in the first, yet the second line gives the error as shown, whereas the first is just fine. 以下两行之间的唯一区别是在第二行中使用var
作为类型推断,而在第一行中使用显式类型Random
,而第二行则给出如图所示的错误,而第一行则很好。
Random x = new Random() ?? (x = new Random()); // ok
var y = new Random() ?? (y = new Random()); // CS0841
// ^-------- error here
CS0841: Cannot use local variable 'y' before it is declared CS0841:在声明之前不能使用局部变量'y'
What is it precisely about the second line that makes the outcome uncertain? 第二条线是什么让结果不确定?
From the hubub I cited above, I learned that the possibility of the left-side of the ??
从我上面提到的hubub,我了解到左侧的可能性??
operator being null
introduces a dependency on the runtime determination of the actual instantiated type of its right-side. operator为null
引入了对其右侧的实际实例化类型的运行时确定的依赖性。 Hmm, ok, I guess,... whatever that means? 嗯,好吧,我想,......这意味着什么? Maybe the amount of alarm generally wafting about the ??
也许警报的数量一般都在飘荡??
operator on this site should have been some kind of dire warning... 这个网站上的运营商应该是某种可怕的警告......
Zeroing-in now, I thought that the whole point of the var
keyword (as very specifically opposed to dynamic
) was that it was not suscceptible to runtime considerations like that, by definition . 现在归零,我认为var
关键字的整个要点(与dynamic
非常特别相反)是, 根据定义 ,它不像运行时那样容易受到影响 。
In other words, even if we adopt the conservative but perfectly defensible rule of "never peering beyond any assignment =
operator", such that we therefore get no helpful information whatsoever from the right-side of the ??
换句话说,即使我们采取“永不窥视超越任何分配保守的,但完全站得住脚规则=
运算符”,这样,我们因此与的右侧任何没有得到有用的信息??
, then based on the left-side alone, the overall result must be "compatible with" Random
. ,然后单独基于左侧,整体结果必须 “兼容” Random
。 That is, the result must be Random
or a more specific (derived) type; 也就是说,结果必须是Random
或更具体的(派生的)类型; it cannot be more general. 它不能更一般。 By definition, therefore, shouldn't Random
be the inferred type, for this compile-time use of var
? 因此,根据定义,不应该将Random
作为推断类型,因为这个编译时使用var
?
As far as I can understand, corrupting var
with runtime considerations summarily defeats its purpose. 据我所知,用运行时考虑因素破坏var
使其失败。 Isn't that precisely what dynamic
is for? 这不正是dynamic
的意义吗? So I guess the questions are: 所以我猜问题是:
dynamic
have been implemented without corrupting the purity of static typing? 如果不破坏静态类型的纯度, dynamic
是否已经实现? var
just maintain a policy of strict conservatism-- always inferring the most-specific type that can be statically inferred--at the same time as the null-coalescing operator is doing whatever it wants to do based on information from the future? 为什么var
不能保持严格保守主义的策略 - 总是推断出可以静态推断的最具体的类型 - 同时空归合运算符根据来自的信息做任何想做的事情。未来? It's not a runtime consideration. 这不是运行时考虑因素。
The compile time type of a variable declared using var
is the static type of its initializer. 使用var
声明的变量的编译时类型是其初始化程序的静态类型。 The static type of a ??
静态类型??
expression is the common type of the static type of both operands. expression是两个操作数的静态类型的常见类型。 But the static type of the second operand is the static type of y
, which isn't known. 但是第二个操作数的静态类型是y
的静态类型,这是未知的。 Therefore the static type of the whole initializer is unknown, and deduction fails. 因此,整个初始化程序的静态类型是未知的,并且扣除失败。
It's true that there exist types for which the initialization would be consistent, but they can't be found using the C# inference rules. 确实存在初始化一致的类型,但是使用C#推理规则无法找到它们。
When you use var
, the type is figured out at compile time. 使用var
,类型在编译时计算出来。 Therefore, when you write this: 因此,当你写这个:
var y = new Random() ?? (y = new Random());
the compiler cannot determine what y
's type is at compile time and thus starts yelling-the decision whether the left side of ??
编译器无法确定编译时y
的类型是什么,因此开始大喊大叫 - 决定是否左侧??
is null or not, will be determined at runtime. 是否为null,将在运行时确定。
A better example would be: 一个更好的例子是:
public interface IA { void Do(); }
public class A : IA { ... }
public class B : IA { ... }
A a = null;
var something = a ?? new B();
What should be the type of something
: IA
, A
or B
? 应该是什么类型的something
: IA
, A
还是B
?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.