【发布时间】:2018-07-01 02:28:39
【问题描述】:
考虑一个不包含任何引用字段的结构(只有基本类型和其他结构)。
考虑到这个结构将在集合中使用,我希望它表现得像一个值类型(即 int)。
- 是否需要覆盖 operator== 和 operator!=?
- 我需要覆盖 Equals 吗?
- 我需要复制构造函数吗?
- 我需要担心分配吗?
- 我需要重写 GetHashCode 吗?
【问题讨论】:
考虑一个不包含任何引用字段的结构(只有基本类型和其他结构)。
考虑到这个结构将在集合中使用,我希望它表现得像一个值类型(即 int)。
【问题讨论】:
特别是如果您的值类型包含引用的字段 类型,您应该重写 Equals(Object) 方法。这可以改善 性能,使您能够更紧密地代表 类型的相等性。
最好实现 IEquatable 以避免装箱(默认 Equals 接受对象类型,因此您的结构必须进行装箱以适应该类型)。 集合(数组、字典等)通常会检查其成员是否实现了 IEquatable,并且会使用 IEquatable.Equals,因此最好实现它。 还建议实现默认的 Equals(来自 System.Object)并直接到 IEquatable.Equals 实现。 示例:
struct MyStruct : IEquatable<MyStruct>
{
public int A { get; set; }
public int B { get; set; }
public bool Equals(MyStruct other)
{
return A == other.A && B == other.B;
}
public override bool Equals(object obj)
{
if (!(obj is MyStruct)) return false;
return ((MyStruct)obj).Equals(this);
}
public override int GetHashCode()
{
return (A, B).GetHashCode();
}
}
我还提供了一个如何实现GetHashCode的例子,最好的方法是使用Tuple的实现。
同样,实现 == 和 != 取决于您 标准库(System、System.Collections 等)使用 System.Equals 或 IEquatable.Equals 进行比较,您也应该这样做。
所以不,不需要实现 == 和 !=。
【讨论】: