当重载相等运算符时,处理空值的最佳方法是什么?

时间:2011-02-01 21:03:35

标签: c# .net operator-overloading equality

  

可能重复:
  How do I check for nulls in an ‘==’ operator overload without infinite recursion?

说我有这样的类型:

public class Effect
{
    public static bool operator == ( Effect a, Effect b )
    {
        return a.Equals ( b );
    }

    public static bool operator != ( Effect a, Effect b )
    {
        return !a.Equals ( b );
    }

    public bool Equals ( Effect effect )
    {
        return this.TypeID.Equals ( effect.TypeID );
    }

    public override bool Equals ( object obj )
    {
        return this.TypeID.Equals ( ( ( Effect ) obj ).TypeID );
    }
}

处理空值的最强大,最干净的方法是什么?

我不确定是否必须为当前实例(this)和传递的实例(effect/obj)检查null?如果我对当前实例(this)使用null,编译器是否仍会调用effect.Equals或Object.Equals?

也可以在哪里进行空检查?我只假设在Equals方法中,而不是相等运算符(==, !=)。

6 个答案:

答案 0 :(得分:2)

首先,this永远不会是null,至少不会出现在C#编译器生成的代码中。

其次,使用ReferenceEquals方法检查null引用,而不必调用==的重载版本(或执行((object) sometypeinstance) == null)。

答案 1 :(得分:2)

Visual Studio有一个代码段,为您提供基本的Equals()实现。我会遵循这一点,除非你有充分的理由不这样做。

// override object.Equals
public override bool Equals(object obj)
{
    //       
    // See the full list of guidelines at
    //   http://go.microsoft.com/fwlink/?LinkID=85237  
    // and also the guidance for operator== at
    //   http://go.microsoft.com/fwlink/?LinkId=85238
    //

    if (obj == null || GetType() != obj.GetType())
    {
        return false;
    }

    // TODO: write your implementation of Equals() here
    throw new NotImplementedException();
    return base.Equals(obj);
}

// override object.GetHashCode
public override int GetHashCode()
{
    // TODO: write your implementation of GetHashCode() here
    throw new NotImplementedException();
    return base.GetHashCode();
}

答案 2 :(得分:1)

怎么样

public static bool operator == ( Effect a, Effect b )     
{  
    return object.Equals(a, b);
}

Object.Equals()的默认实现为您执行空检查。

如果你很好奇,这就是Object.Equals()的用法(由.NET Reflector提供):

public static bool Equals(object objA, object objB)
{
    return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB)));
}

答案 3 :(得分:0)

有必要使用参数制作课程的每个方法检查空值。

public class Effect
{
    public static bool operator == ( Effect a, Effect b )
    {
        if (a == null) && (b == null) return true;
            if (a == null) return false;
            return a.Equals ( b );
    }

    public static bool operator != ( Effect a, Effect b )
    {
        return !(a == b);
    }

    public bool Equals ( Effect effect )
    {
            if (b == null) return false;
        return this.TypeID.Equals ( effect.TypeID );
    }

    public override bool Equals ( object obj )
    {
            if (obj == null) return false;
        return this.TypeID.Equals ( ( ( Effect ) obj ).TypeID );
    }
}

要注意的其他事项是GetHashCode,如果实现相等则应该实现,而GetHashCode应该只在不可变属性上实现,如果此对象将用于比较项目的字典或类似对象中使用哈希码。

答案 4 :(得分:-1)

添加:

 public static bool operator == ( Effect a, Effect b )     
 {  
     return a is Effect && b is Effect && a.TypeID.Equals (b.TypeID);    
 }  
 public static bool operator != ( Effect a, Effect b )
 {         
     return !(a == b );     
 }      
 public bool Equals ( Effect effect )     
 {         
    return this == effect );     
 }      
 public override bool Equals ( object obj )     
 {   
    return obj is Effect && this == obj); 
 } 

或代替最后一次投放:

 public override bool Equals ( object obj )     
 {   
    if (obj == null) throw new ArgumentNullException(
         "obj", "obj is null");
    if (!(obj is effect)) throw new ArgumentException(
         "obj", "obj is not an effect");
    return obj is Effect && this == obj); 
 }

答案 5 :(得分:-1)

是的,你应该反对null。你为什么害怕这个?

请记住,当您使用equals时,您可能还想查看hashcode方法!这两种方法交织在一起。