我已经阅读了许多关于空合并??
运算符的 SO 问题,但它们似乎都没有解决以下具体问题,既不涉及可空性(这里)、运算符优先级(这里和这里),也不是特别是隐式转换(这里、这里、这里和这里)。我还阅读了.NET 文档(更多在这里)并尝试阅读官方规范,但遗憾的是无济于事。
所以这里。以下两行之间的唯一区别是在第二行中使用var
for 类型推断,而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
,它不受运行时考虑的影响。
换句话说,即使我们采用“从不超越任何赋值=
运算符”的保守但完全可以辩护的规则,这样我们因此无法从 的右侧获得任何有用的信息??
,然后仅基于左侧,整体结果必须“兼容” Random
。也就是说,结果必须是Random
或更具体的(派生的)类型;它不能更普遍。因此,根据定义,不Random
应该是推断的类型,因为var
?
据我所知,var
由于运行时的考虑而破坏它会破坏它的目的。这不正是dynamic
为了这个吗?所以我想问题是:
- 空合并运算符是我理解 C# 静态(即编译时)类型哲学的唯一和/或罕见的例外吗?
- 如果是,那么这种设计与这里似乎正在发生的事情之间的好处或权衡是什么,即故意将非确定性引入静态类型推断系统,而它以前没有表现出来?
dynamic
如果不破坏静态类型的纯度,就不能实现吗? - 强类型的要点之一难道不是通过向开发人员提供可操作的反馈来实现编译时设计的严谨性吗?为什么不能
var
只维持严格保守的政策——总是推断出可以静态推断的最具体的类型——同时空合并运算符根据来自未来的信息做任何它想做的事情?