ser*_*0ne 4 .net c# boolean equality exception
每当我写一个新的class或者struct可能存有一些数据时,可能需要进行比较,我总是实现,IEquatable<T>因为这提供了class/struct一个强类型的.Equals(T other)方法.
例:
public struct Radius : IEquatable<Radius>
{
public Int32 TopLeft { get; set; }
public Int32 TopRight { get; set; }
public Int32 BottomLeft { get; set; }
public Int32 BottomRight { get; set; }
public bool Equals(Radius other)
{
return this.TopLeft == other.TopLeft
&& this.TopRight == other.TopRight
&& this.BottomLeft == other.BottomLeft
&& this.BottomRight == other.BottomRight;
}
}
Run Code Online (Sandbox Code Playgroud)
除了提供实现之外.Equals(Radius other),我还应该覆盖默认实现(.Equals(object obj))
我有两个选择,我的问题是,哪些实现更好?
选项1是使用铸造:
public override bool Equals(object obj)
{
return this.Equals((Radius)obj);
}
Run Code Online (Sandbox Code Playgroud)
选项2是使用"as"关键字:
public override bool Equals(object obj)
{
return this.Equals(obj as Radius);
}
Run Code Online (Sandbox Code Playgroud)
我之所以问这个是,利用铸造将抛出一个异常,如果obj不能转换为Radius,而as将解析null,如果它无法施展,所以只检查this对null未抛出异常; 那么抛出一个异常,还是只返回更好false?
编辑:正如很多SO的同事所指出的,结构不能为空,因此第二个选项不适用于结构.因此,另一个问题浮出水面:.Equals(object obj)结构和类的重写实现是否相同?
正如已经提到的@SLaks Equals()绝不应该抛出。
在这种特殊情况下,我认为is结合使用运算符和强制转换应该可以帮助您:
public override bool Equals(object obj)
{
if(obj is Radius)
return Equals((Radius)obj);
return false;
}
Run Code Online (Sandbox Code Playgroud)
如果您有a class,则只需使用as运算符:
public override bool Equals(object obj)
{
return Equals(obj as MyObj);
}
public bool Equals(MyObj obj)
{
if(ReferenceEquals(obj, null))
return false;
// ToDo: further checks for equality.
}
Run Code Online (Sandbox Code Playgroud)