没有引用类型的 c# struct

标签 c# c#-7.0

考虑一个不包含任何引用字段的结构(仅包含基本类型和其他结构)。

考虑到这个结构将在集合中使用,我希望它表现得像一个值类型(即 int)。

  • 我需要覆盖 operator== 和 operator!= 吗?
  • 我需要覆盖 Equals 吗?
  • 我需要拷贝构造函数吗?
  • 我需要担心作业吗?
  • 我需要覆盖 GetHashCode 吗?

最佳答案

  1. 取决于您,默认情况下 == 和 != 将重定向到默认的 Equals 实现,但直接使用 Equals 而不是 == 或 != 被认为是更好的做法
  2. 默认情况下,Equals 应该对值类型执行按位比较,对引用类型执行引用相等性,因此如果您的结构包含引用类型的字段,您将需要覆盖 Equals 以对它们执行适当的比较。除此之外,MSDN 建议无论如何都要覆盖 Equals,以提高性能。

Particularly if your value type contains fields that are reference types, you should override the Equals(Object) method. This can improve performance and enable you to more closely represent the meaning of equality for the type.

  1. 在变量/方法之间传递时,默认情况下会复制结构,因此无需编写复制构造函数。我能想到的唯一情况是,如果您的结构包含引用类型的字段,并且您想创建一个复制构造函数来对它们执行深度复制,这取决于您。
  2. 担心作业是什么意思?
  3. 是的。如果您打算将您的结构用作 HashSet 的成员或用作字典中的键,则您需要提供 GetHashCode 的自定义实现。

最好实现 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 进行比较,您也应该这样做。

所以不,没有必要实现 == 和 !=。

关于没有引用类型的 c# struct,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51119953/

相关文章:

c# - 将 [Key] 属性分配给 Entity Framework 生成的类 - MVC4 C#

c# - Roslyn 功能/模式分支 (C# 7) - 如何启用实验性语言功能

c# - 在 C# 中使用丢弃作为返回方法

tuples - C# 7.0 中的元组文字能否启用面向方面的编程

c# - 动态创建控件的事件处理程序

c# - 在 C# 中,+= 和 =+ 之间有什么区别吗?

c# - 为什么ref参数不能像out参数一样被忽略?

c# - 在 VSTS 中启用 C# 7 支持

c# - WPF:如何高效地每秒更新图像 30 次

c# - 使用 C# 检查 Internet 连接是否可用