繁体   English   中英

来自'??'的C#类型推断(“var”)赋值null-coalescing运算符

[英]C# type inference (“var”) assignment from '??' null-coalescing operator

我已经阅读了关于空合并的许多SO问题?? 运算符但它们似乎都没有解决以下特定问题,它既不涉及可空性此处 ), 运算符优先级此处此处 ),也不涉及隐式转换此处此处此处此处 )。 我也阅读了.NET文档 (更多这里 )并尝试阅读官方规范 ,但遗憾的是都无济于事。


所以这里。 以下两行之间的唯一区别是在第二行中使用var作为类型推断,而在第一行中使用显式类型Random ,而第二行则给出如图所示的错误,而第一行则很好。

Random x = new Random() ?? (x = new Random());        // ok

var    y = new Random() ?? (y = new Random());        // CS0841
                        //  ^-------- error here

CS0841:在声明之前不能使用局部变量'y'

第二条线是什么让结果不确定?

从我上面提到的hubub,我了解到左侧的可能性?? operator为null引入了对其右侧的实际实例化类型的运行时确定的依赖性。 嗯,好吧,我想,......这意味着什么? 也许警报的数量一般都在飘荡?? 这个网站上的运营商应该是某种可怕的警告......

现在归零,我认为var关键字的整个要点(与dynamic非常特别相反)是, 根据定义 ,它不像运行时那样容易受到影响

换句话说,即使我们采取“永不窥视超越任何分配保守的,但完全站得住脚规则=运算符”,这样,我们因此与的右侧任何没有得到有用的信息?? ,然后单独基于左侧,整体结果必须 “兼容” Random 也就是说,结果必须是Random或更具体的(派生的)类型; 它不能更一般。 因此,根据定义,不应该将Random作为推断类型,因为这个编译时使用var

据我所知,用运行时考虑因素破坏var使其失败。 这不正是dynamic的意义吗? 所以我猜问题是:

  • 对于我对C#静态(即编译时)打字哲学的理解, null-coalescing运算符是一个单独的和/或罕见的例外吗?
  • 如果是,那么这个设计与这里似乎正在发生的事情之间的好处或权衡是什么,即故意将非确定性引入静态类型推理系统,以及之前没有表现出来的? 如果不破坏静态类型的纯度, dynamic是否已经实现?
  • 通过对开发人员的可操作反馈来实现编译时设计的严谨性不是强类型的要点之一吗? 为什么var不能保持严格保守主义的策略 - 总是推断出可以静态推断的最具体的类型 - 同时空归合运算符根据来自的信息做任何想做的事情。未来?

这不是运行时考虑因素。

使用var声明的变量的编译时类型是其初始化程序的静态类型。 静态类型?? expression是两个操作数的静态类型的常见类型。 但是第二个操作数的静态类型是y的静态类型,这是未知的。 因此,整个初始化程序的静态类型是未知的,并且扣除失败。

确实存在初始化一致的类型,但是使用C#推理规则无法找到它们。

使用var ,类型在编译时计算出来。 因此,当你写这个:

var    y = new Random() ?? (y = new Random()); 

编译器无法确定编译时y的类型是什么,因此开始大喊大叫 - 决定是否左侧?? 是否为null,将在运行时确定。

一个更好的例子是:

public interface IA { void Do(); }
public class A : IA { ... }
public class B : IA { ... }

A a = null;
var something = a ?? new B(); 

应该是什么类型的somethingIAA还是B

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM