如何解决C#结构中的“ IEquatable.Equals”中的空处理
使用Java多年之后,我已经有一段时间没有使用C#了。因此,我刚刚(重新)了解到struct
是非空值类型。到目前为止一切顺利。
我有一个struct Coordinate
实现了IEquatable
:
public struct Coordinate : IEquatable<Coordinate>
{
public Coordinate(double x,double y,Projection proj)
{
this.X = x;
this.Y = y;
this.Proj = proj;
}
public double X { get; }
public double Y { get; }
public Projection Proj { get; }
public bool Equals(Coordinate other)
{
return X == other.X && Y == other.Y && Proj == other.Proj;
}
public override string ToString()
{
return $"x={X},y={Y},projection={Proj}";
}
}
我收到一个编译器警告,不允许我在null
中执行other != null
检查(Equals(Coordinate)
),但是我可以调用ltown.Equals(null)
返回false
:
Coordinate ltown = new Coordinate(-65.17,44.88,Projection.Mercator);
Console.WriteLine(ltown.Equals(null)); // prints false
为什么在传递null
时应用程序不会崩溃?
这有什么魔术?如果我将Coordinate作为类而不是结构实现,则会崩溃。这也是我在这里的期望。
更新
Etienne de Martel提供了正确的答案。我问过大杂烩,应该知道。但是,我对IEquatable
和类和结构在行为上有所不同的事实感到分心。关于后者,我做了进一步的测试...
实现IEquatable.Equals(Coordinate)
,Object.Equals(object)
和Object.GetHashCode()
:
-
Equals(c)
(而c
是Coordinate
)总是调用IEquatable.Equals(Coordinate)
。
但如果c
为null
,则结构和类的行为似乎有所不同:
- 如果
Coordinate
是一个类:IEquatable.Equals(Coordinate)
被调用 - 如果
Coordinate
是一个结构:Object.Equals(object)
被调用
解决方法
由于无法将null
隐式转换为值类型,因此请执行以下操作:
ltown.Equals(null)
调用的方法不是您编写的bool Equals(Coordinate other)
,而是从Equals(object)
继承的默认Object
(从技术上讲,它是您从{{1 }},但在这种情况下并没有太大变化。如果您将ValueType
传递给它,则该实现将始终返回false
。
作为一般规则,在实现null
时应始终重写该方法,并且可以仅委托给自己的实现:
IEquatable<T>
而且,由于您已覆盖public override bool Equals(object other)
{
return other is Coordinate coords && Equals(coords);
}
,因此现在还需要覆盖Equals
。
现在,如果您将GetHashCode
更改为一门课程,而又不碰其他任何内容,则会出现异常,这是由于两个原因:
- 由于您实际上有两个
Coordinate
重载,因此将启动重载解决方案,并调用最合适的一个。事实证明,所选重载因Equals
是引用类型还是值类型而异。如果您想知道为什么,请参阅this question。 - 如果您为引用类型定义
Coordinate
方法,则它需要妥善处理Equals
值,也就是说,在这种情况下,它应该返回null
(因为没有值相等)到false
到null
本身之外,并且由于这是一个实例方法,因此null
不能为this
对于值类型,您当然不需要这样做,因为它们不能为null
。
请注意,在所有情况下,您还应确保参数具有适当的类型。您可以通过巧妙地使用null
运算符将两种检查结合在一起:
as
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。