C# 编写等于运算符时处理空值的最佳方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/86947/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best way to handle null when writing equals operator
提问by George Mauer
Possible Duplicate:
How do I check for nulls in an '==' operator overload without infinite recursion?
When I overload the == operator for objects I typically write something like this:
当我为对象重载 == 运算符时,我通常会这样写:
public static bool operator ==(MyObject uq1, MyObject uq2) {
if (((object)uq1 == null) || ((object)uq2 == null)) return false;
return uq1.Field1 == uq2.Field1 && uq1.Field2 == uq2.Field2;
}
If you don't down-cast to object the function recurses into itself but I have to wonder if there isn't a better way?
如果您不向下转换为对象,则该函数会递归到自身中,但我想知道是否没有更好的方法?
回答by Juanma
ReferenceEquals(object obj1, object obj2)
ReferenceEquals(对象 obj1, 对象 obj2)
回答by Timothy Carter
if ((object)uq1 == null)
return ((object)uq2 == null)
else if ((object)uq2 == null)
return false;
else
//return normal comparison
This compares them as equal when both are null.
当两者都为空时,这会将它们比较为相等。
回答by Purfideas
Follow the DB treatment:
按照DB处理:
null == <anything> is always false
回答by Scott Dorman
@neouser99: That's the right solution, however the part that is missed is that when overriding the equality operator (the operator ==) you should also override the Equals function and simply make the operator call the function. Not all .NET languages support operator overloading, hence the reason for overriding the Equals function.
@neouser99:这是正确的解决方案,但是遗漏的部分是在覆盖相等运算符(运算符 ==)时,您还应该覆盖 Equals 函数并简单地让运算符调用该函数。并非所有 .NET 语言都支持运算符重载,因此是覆盖 Equals 函数的原因。
回答by Philip Rieck
As Microsoft says,
正如微软所说,
A common error in overloads of operator == is to use (a == b), (a == null), or (b == null) to check for reference equality. This instead results in a call to the overloaded operator ==, causing an infinite loop. Use ReferenceEquals or cast the type to Object, to avoid the loop.
运算符 == 重载中的一个常见错误是使用 (a == b)、(a == null) 或 (b == null) 来检查引用相等性。这反而会导致调用重载的运算符 ==,从而导致无限循环。使用 ReferenceEquals 或将类型强制转换为 Object,以避免循环。
So use ReferenceEquals(a, null) || ReferenceEquals(b, null) is one possibility, but casting to object is just as good (is actually equivalent, I believe).
所以使用 ReferenceEquals(a, null) || ReferenceEquals(b, null) 是一种可能性,但转换为对象也一样好(我相信实际上是等效的)。
So yes, it seems there should be a better way, but the method you use is the one recommended.
所以是的,似乎应该有更好的方法,但您使用的方法是推荐的方法。
However, as has been pointed out, you really SHOULD override Equals as well when overriding ==. With LINQ providers being written in different languages and doing expression resolution at runtime, who knows when you'll be bit by not doing it even if you own all the code yourself.
但是,正如已经指出的那样,在覆盖 == 时,您确实应该也覆盖 Equals。由于 LINQ 提供程序是用不同的语言编写的,并且在运行时进行表达式解析,即使您自己拥有所有代码,谁知道什么时候不这样做会受到影响。
回答by xtofl
But why don't you create an object member function? It can certainly not be called on a Null reference, so you're sure the first argument is not Null.
但是为什么不创建一个对象成员函数呢?它当然不能在 Null 引用上调用,因此您确定第一个参数不是 Null。
Indeed, you lose the symmetricity of a binary operator, but still...
事实上,你失去了二元运算符的对称性,但仍然......
(note on Purfideas' answer: Null might equal Null if needed as a sentinel value of an array)
(请注意 Purfideas 的回答:如果需要作为数组的哨兵值,Null 可能等于 Null)
Also think of the semantics of your == function: sometimes you reallywant to be able to choose whether you test for
还要考虑 == 函数的语义:有时您真的希望能够选择是否测试
- Identity (points to same object)
- Value Equality
- Equivalence ( e.g. 1.000001 is equivalent to .9999999 )
- 身份(指向同一个对象)
- 价值平等
- 等价(例如 1.000001 相当于 .9999999 )
回答by ripper234
Just use Resharper to create you Equals & GetHashCode methods. It creates the most comprehensive code for this purpose.
只需使用 Resharper 来创建 Equals 和 GetHashCode 方法。它为此目的创建了最全面的代码。
UpdateI didn't post it on purpose - I prefer people to use Resharper's function instead of copy-pasting, because the code changes from class to class. As for developing C# without Resharper - I don't understand how you live, man.
更新我不是故意发布的 - 我更喜欢人们使用 Resharper 的函数而不是复制粘贴,因为代码会因类而异。至于在没有 Resharper 的情况下开发 C# - 我不明白你是怎么生活的,伙计。
Anyway, here is the code for a simple class (Generated by Resharper 3.0, the older version - I have 4.0 at work, I don't currently remember if it creates identical code)
无论如何,这是一个简单类的代码(由 Resharper 3.0 生成,旧版本 - 我有 4.0 在工作,我目前不记得它是否创建了相同的代码)
public class Foo : IEquatable<Foo>
{
public static bool operator !=(Foo foo1, Foo foo2)
{
return !Equals(foo1, foo2);
}
public static bool operator ==(Foo foo1, Foo foo2)
{
return Equals(foo1, foo2);
}
public bool Equals(Foo foo)
{
if (foo == null) return false;
return y == foo.y && x == foo.x;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(this, obj)) return true;
return Equals(obj as Foo);
}
public override int GetHashCode()
{
return y + 29*x;
}
private int y;
private int x;
}