我已经阅读了关于空合并??
运算符的许多SO问题,但它们似乎都没有解决以下特定问题,它既不涉及可空性({{3} }),运算符优先级(here和here),特别是隐式转换(here,here,{ {3}}和here)。我还阅读了here(更多here)并尝试阅读.NET docs,但遗憾的是都无济于事。
所以这里。以下两行之间的唯一区别是在第二行中使用var
进行类型推断,而在第一行中使用显式类型Random
,而第二行则给出如图所示的错误,而第一行是很好。
Random x = new Random() ?? (x = new Random()); // ok
var y = new Random() ?? (y = new Random()); // CS0841
// ^-------- error here
CS0841:在声明
之前,不能使用局部变量'y'
使结果不确定的第二行究竟是什么?
从上面引用的hubub中,我了解到??
运算符左侧null
的可能性引入了对其权利的实际实例化类型的运行时确定的依赖性 - 侧。嗯,好吧,我想,......这意味着什么?通常这个网站上??
运营商的警报声通常都是警告......
现在归零,我认为var
关键字的整个点(非常明确地反对dynamic
)是因为它不容易受到运行时考虑因素的影响, < em>按照定义 。
换句话说,即使我们采用保守但完全可辩护的“从不窥视任何任务=
运算符”的规则,因此我们从{{的右侧 - 得不到任何有用的信息。 1}},然后仅基于左侧,整体结果 必须 与“??
”兼容。也就是说,结果必须是Random
或更具体(派生)的类型;它不能更一般。因此,对于Random
的编译时使用,根据定义,Random
不应该是推断类型?
据我所知,用运行时考虑因素破坏var
会使其失败。这不正是var
的意思吗?所以我想问题是:
dynamic
无法实现?dynamic
不能保持严格保守主义的政策 - 始终推断可以静态推断的最具体的类型 - 同时因为null-coalescing运算符是根据未来的信息做任何想做的事情?答案 0 :(得分:4)
这不是运行时考虑因素。
使用var
声明的变量的编译时类型是其初始值设定项的静态类型。 ??
表达式的静态类型是两个操作数的静态类型的常见类型。但是第二个操作数的静态类型是y
的静态类型,这是未知的。因此整个初始化程序的静态类型是未知的,并且演绎失败。
确实存在初始化一致的类型,但使用C#推理规则无法找到它们。
答案 1 :(得分:0)
使用var
时,类型在编译时计算出来。因此,当你写这个:
var y = new Random() ?? (y = new Random());
编译器在编译时无法确定y
的类型是什么,因此开始大喊 - 判断??
的左侧是否为空,将在运行时确定。
更好的例子是:
public interface IA { void Do(); }
public class A : IA { ... }
public class B : IA { ... }
A a = null;
var something = a ?? new B();
something
的类型应该是什么:IA
,A
或B
?