当我必须为
实现相等比较器时public class SampleClass
{
public int Prop { get; set; }
}
我应该
null == new SampleClass()
和
new SampleClass() == null
和
new SampleClass().Equals(null)
假?
那么
new SampleClass() != null
它也应该是假的吗?
更新人们质疑这个问题背后的原因。这应该是 !=和==永远是对立的。但是如果我实现这些方法所以所有这些比较都会导致错误,那么将会出现==和!=运算符会产生相同结果的情况。因此,是否应该返回true或false是一个两难的选择。
答案 0 :(得分:7)
这甚至是个问题吗?不,null
永远不应该等于一个对象。
修改:因此,new SampleClass() != null
的扩展名应为true
。 null
与NaN
不同;它的定义非常明确。
答案 1 :(得分:4)
你的例子中所有与null相等的比较肯定是假的。最后一个也很重要:
new SampleClass() != null
这一定必须评估为true
,因为这是检查引用变量是否已初始化的常用方法。如果要评估false
,它可能无意中在整个地方重新分配变量,因为C#开发人员期望来自运营商的某种行为。另一个例子:
SampleClass myVar = new SampleClass();
// Various stuff happening here, possibly setting myVar to null
if (myVar != null)
{
// Programmer go "WTFBBQ?" when he finds this doesn't get executed
myVar.DoStuff();
}
困惑,程序员将其更改为:
if (myVar == null)
{
myVar = new SampleClass();
}
myVar.DoStuff(); // null reference exception, huh?
答案 2 :(得分:2)
除了陈述的内容外,请注意:
预定义的引用类型相等运算符是:
bool operator ==(object x, object y);
bool operator !=(object x, object y);
...所以
SampleClass a = null;
SampleClass b = null;
阅读.NET框架设计人员在该问题上所说的内容:
Why don't nullable relational operators return “bool?” instead of “bool“?
有关详细信息,请阅读:
答案 3 :(得分:1)
我不确定我是否完全理解你的问题,但是null(根据定义)不是一个值。因此,
null == new SampleClass()
没有任何意义(并且,实际上,其他比较都没有)。
你能改一下你的问题吗?
答案 4 :(得分:1)
正如其他人所说,null永远不会等于包括null在内的任何其他东西。这是因为null不是值,而是缺少值。
对于您的具体问题,您似乎正在尝试实例化尚未初始化的对象,并且您想要确定该对象是否已初始化。我的建议是包含一个属性,指示对象是否已初始化。
答案 5 :(得分:1)
Null永远不应该等于非null引用。通过扩展,你的!=应该返回true,因为它与相等相反。
答案 6 :(得分:0)
如果你有一个对象的实例,你没有null,所有相等的比较器都应该尊重它。
答案 7 :(得分:0)
我认为这是一个特别有趣的问题。我对它的看法与任何答案都不完全相同,所以请耐心等待我的到来。
首先要注意的是,.NET中的null
在某些其他上下文中与null
并不完全相同,但它可用于对它们进行建模。
在SQL中,我们可能1 = null
和1 <> null
都返回null
,因为null
的概念更接近数学,其中null不是等于任何东西,包括null,但也不等于任何东西。
如果需要,我们可以使用C#null
,但这并不完全是.NET中null
的默认含义。
对于任何引用类型,null具有特定的定义含义,可能还有上下文提供的其他含义。
具体含义是“没有这种类型的对象的实例”。
给定上下文中的附加含义可能是“整数值实际上是空的,而不是匹配任何整数”,或者“没有这样的项目集合,甚至不是空的”,或者“这是第一个这样的项目,所以没有早期的“等等,取决于我们如何使用它。 (另外,它可能意味着“哦,亲爱的,真的不应该是空的,最好抛出异常”)。
现在,我们可能希望大量使用这些附加含义,以至于我们定义了一个对象等于null有意义的情况,或者至少不等于null。但是,我们有以下限制:
对于引用类型的值,null的特定定义意味着没有该引用类型的实例不会消失。
对于给定的x和y,x == y
始终会给x != y
提供相反结果的语义不会消失。
因此:
如果我们想要一个实例可以等于null的类型,它必须是一个值类型。
我们仍然需要x != null
返回x == null
的反面。
现在,自从.NET 2.0以来,我们已经有了一个内置的功能:Nullable<T>
(或C#语法中的T?
)。它还有一些额外的支持,以帮助它在拳击面前表现良好(这使得它在人的方式表现得像一个参考类型,所以如果没有额外的支持我们会有并发症x == null
将返回true但是(object)x == null
会返回false。
情况也是如此,Nullable<T>
可以处理几乎任何我们想要使用这种稍微不同的语义为null的情况,这意味着没有任何案例可以留下来。我们可能想要定义一个Equals()
方法,该方法在传递null时返回true。