Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在IEquatable<;T>;是否需要执行参考检查_C#_Equals_Iequatable - Fatal编程技术网

C# 在IEquatable<;T>;是否需要执行参考检查

C# 在IEquatable<;T>;是否需要执行参考检查,c#,equals,iequatable,C#,Equals,Iequatable,我有一个类,它包含IEquatable。是否有必要在Equals()中执行引用检查,还是在框架中处理 class Foo : IEquatable<Foo> { int value; Bar system; bool Equals(Foo other) { return this == other || ( value == other.value && system.Equals(other.sys

我有一个类,它包含
IEquatable
。是否有必要在
Equals()
中执行引用检查,还是在框架中处理

class Foo : IEquatable<Foo>
{
    int value;
    Bar system;

    bool Equals(Foo other)
    {
        return this == other || 
        ( value == other.value && system.Equals(other.system) );
    }
}

感谢您的回复。

我认为有必要检查
this==other
,因为您定义了自己的
等于。如果您不希望它被指针检查,那么您可以编写自己的
IEquatable

从某种意义上说,它不是正确性所必需的,但是框架肯定不会“处理它”,因此它可能很有用,通常是出于性能原因

一点:如果实现由
EqualityComparer.Default
包装,那么如果一个或两个参数都是
null
,它就不会输入用户代码,因此在这种情况下,它会执行某种程度的引用检查(如果不是完整的
ReferenceEquals(x,y)

主题外,示例方法中存在几个空解引用问题(
other
可能是
null
this.system
可能是
null

我会把你的方法写成这样:

public bool Equals(Foo other)
{
    if(other == null)
         return false;

    if(other == this)
         return true;

    return value == other.value
            && EqualityComparer<Bar>.Default.Equals(bar, other.bar)
            // You don't *have to* go down the EqualityComparer route
            // but you do need to make sure you don't dereference null.
public bool Equals(Foo-other)
{
如果(其他==null)
返回false;
如果(其他==此)
返回true;
返回值==other.value
&&EqualityComparer.Default.Equals(bar,其他.bar)
//你不必走平等比较路线
//但您确实需要确保不取消对null的引用。
}

还记得在编写自己的等式比较时重写
GetHashCode

IEquatable
是一个接口;实现取决于实现者


因为您正在实现接口,所以您要负责接口定义的所有预期行为。

我认为这是必要的。参照检查是比较对象时可以执行的第一个快速步骤

在您给出的示例中,确保在访问其值之前检查other是否为null

bool Equals(Foo other)
{
    if(other == null) return false;

    if(this == other) return true;

    // Custom comparison logic here.
}

这通常是一种优化——这将是一个奇怪的
Equals
实现,如果没有它,它将失败。因此,我不认为这是必要的,但也不认为它“在框架内得到处理”。我是一个廉价的优化实现,所以它通常值得包括在内


请注意,如果您也在重载
==
,那么您可能应该使用
object.ReferenceEquals
来执行这些比较。

请小心。事实上,我强烈反对这样做,因为如果你想在
等于
方面为你的
Foo
类型重载
==
操作符(在我的经验中通常是这样),你会发现你自己有一个无限的递归

为了说明我的意思,这里有一个
==
的常见实现,即
等于

public static bool operator ==(Foo x, Foo y)
{
    // Will overflow the stack if Equals uses ==:
    return !ReferenceEquals(x, null) && x.Equals(y);
}

也就是说,我完全同意使用
ReferenceEquals
来代替它可能是合适的。

用什么方式来代替优化是必要的?如果你删除了它,你会认为行为会有什么不同?考虑一下,你是对的,这不是必要的,但这是一种非常简单的方法,可以判断你要比较的对象是否相等,特别是当你必须比较几个属性以确定相等性时。我认为在这种情况下,我对必要性的定义是“我会鼓励它”;)我发现很难理解为什么这个答案被接受,因为它的第一句话是不正确的…@Andrew:这是一个选择,但我通常更喜欢用Object.ReferenceEquals显式表示——我发现这更容易理解。我是唯一一个认为C#
=
运算符可怕的人吗?在vb.net中,等式检查运算符只能用于实现它的类型;如果希望测试引用相等性,则必须使用
Is
运算符或
IsNot
运算符,这些运算符只能用于测试引用相等性,或针对
Nothing
测试可空类型实例。使用同一个运算符来表示引用相等和值相等,使用非虚拟重载,会造成混乱。@supercat:我喜欢它在那里,但觉得它在绝大多数情况下被误用了。基本上,我更愿意生活在这样一个世界里,
=
总是用于引用类型的引用相等。(事实上,即使对于字符串,我也很乐意遵守这条规则。)但我确实看到了自定义值类型的吸引力。IMHO,正确的做法是像vb.net那样使用不同的运算符实现引用相等和逻辑相等。有一个操作符用于引用相等是有帮助的,但有一个操作符用于基于静态绑定的引用相等(可能是也可能不是)是没有帮助的。考虑:
public static bool IsEqual(T obj1,T obj2),其中T:class{return obj1==obj2;}
调用
IsEqual
对包含相同字符序列的两个不同
String
实例应该有什么影响。@supercat:我想我们是一致的。我想我的观点是,如果.NET开发人员能够抵制对其引用类型重载
==
的冲动,并且只对值类型使用它,那么我们就可以得到您按照惯例所描述的东西。这样,它实际上只表示引用相等(这意味着.NET开发人员不会被您的示例搞糊涂,您的示例将为两个相似的字符串返回
false
),除了
int
bool
,等值类型之外,等和自定义值类型。在包含相同字符的两个
string
类型的值可能会比较不相等的情况下(根据上面的泛型示例),使用看起来像值相等运算符的运算符是很难看的,没有无条件测试引用的相等运算符也是很难看的
bool Equals(Foo other)
{
    if(other == null) return false;

    if(this == other) return true;

    // Custom comparison logic here.
}
public static bool operator ==(Foo x, Foo y)
{
    // Will overflow the stack if Equals uses ==:
    return !ReferenceEquals(x, null) && x.Equals(y);
}