c# – 为什么==运算符在没有定义==时为Nullable工作?
我只是在看着
this answer,它包含了Nullable的代码从.NET反射器,我注意到两件事情:
>从Nullable< T>进行显式转换是必需的到T. 鉴于这两个事实,令我惊讶的是,它编译: int? value = 10; Assert.IsTrue(value == 10); 使用代码值== 10,任一值被神奇地转换为int(因此允许使用int的==运算符,或者==运算符正在为Nullable< int>进行神奇定义(或者,我认为不太可能反射器正在遗漏一些代码.) 我期待着要做以下之一: Assert.IsTrue((value.Equals(10)); // works because Equals *is* defined Assert.IsTrue(value.Value == 10); // works because == is defined for int Assert.IsTrue((int?)value == 10); // works because of the explicit conversion 这些当然工作,但==也有效,这是我没有得到的部分. 我注意到这一点,并且提出这个问题的原因是我正在尝试编写一个类似于Nullable< T>的结构.我从上面的反射器代码开始,只做了一些很小的修改.不幸的是,我的CustomNullable< T>不一样的方式.我不能做Assert.IsTrue(value == 10).我得到“运算符==不能应用于类型CustomNullable< int>和int”的操作数. 现在,不管修改多么小,我不会期望能做到… CustomNullable<T> value = null; 因为我知道有一些编译器魔术背后的Nullable< T>这允许将值设置为null,即使Nullable
只有这两个事实,这是令人惊讶的. 这是第三个事实:在C#中,大多数运算符被“解除为空”. 通过“解除为空”,我的意思是说如果你说: int? x = 1; int? y = 2; int? z = x + y; 那么你得到的语义为“如果x或y为空,那么z为空,如果两者都不为null,则添加它们的值,转换为可空,并将结果分配给z. 平等的情况也是如此,尽管平等有点奇怪,因为在C#中,平等依然只有两重价值.要正确提升,平等应该是三值的:如果x或y为空,则x == y应为null,如果x和y都为非空,则为true或false.这是它在VB中的工作原理,但不是在C#中.
你将不得不学会生活失望,因为你的期望与现实完全不符.可空< T>是一种非常特殊的类型,它的神奇属性深入C#语言和运行时.例如: > C#自动将运算符提升为可空.没有办法说“自动提升操作符到MyNullable”.您可以通过编写自己的用户定义的运算符来获得相当的接近. 相关文章
点击查看更多相关文章
转载注明原文:c# – 为什么==运算符在没有定义==时为Nullable工作? - 代码日志 解决方法
只有这两个事实,这是令人惊讶的. 这是第三个事实:在C#中,大多数运算符被“解除为空”. 通过“解除为空”,我的意思是说如果你说: int? x = 1; int? y = 2; int? z = x + y; 那么你得到的语义为“如果x或y为空,并将结果分配给z. 平等的情况也是如此,但不是在C#中.
你将不得不学会生活失望,它的神奇属性深入C#语言和运行时.例如: > C#自动将运算符提升为可空.没有办法说“自动提升操作符到MyNullable”.您可以通过编写自己的用户定义的运算符来获得相当的接近.> C#具有空文字的特殊规则 – 可以将它们分配给可空变量,编译器为它们生成特殊代码.无效的拳击语义是非常奇怪的,并被烘烤到运行时.没有办法效仿他们.>可以使用的语义是,随着和合并的运算符被烘烤到语言中.> Nullables不满足struct约束.没有办法效仿.>等等. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |