使用结构体而不是类来表示简单类型

3

在C#中,如果我使用下面所示的结构体并进行相等比较,则会比较结构体字段的值,如果所有字段具有相同的值,则会得到true结果。这是默认行为。

struct PersonStruct
{
    public PersonStruct(string n,int a)
    {
        Name = n;Age = a;
    }
    public string Name { get; set; }
    public int Age { get; set; }
}

var p1 = new PersonStruct("Jags", 1);

var p2 = new PersonStruct("Jags", 1);

Console.WriteLine(p1.Equals(p2)); //Return True

如果是类,它会返回false,因为类是引用类型。

class PersonClass
{
    public PersonClass(string n, int a)
    {
        Name = n; Age = a;
    }
    public string Name { get; set; }
    public int Age { get; set; }
}
var pc1 = new PersonClass("Jags", 1);
var pc2 = new PersonClass("Jags", 1);

Console.WriteLine(pc1.Equals(pc2));//Returns False

我了解上述概念。我的问题是,考虑到上述情况,使用结构体而不是类是否是一个好主意?我经常看到人们在这种情况下实现类(例如简单的DTO),并做所有额外的工作来实现相等运算符(如IEquatable和重写的equals方法)。
我的理解正确吗,还是我漏掉了什么?

System.ValueType 的默认相等性实现使用反射,效率相对较低。因此,您应该为您的结构体和类实现 IEquatable<T>。对于结构体来说,避免调用 object.Equals 会更加重要,以避免装箱。 - Lee
2
你应该让你的结构体不可变,可变的结构体是有害的 - Lasse V. Karlsen
2个回答

1

这方面有一篇完整的文章在MSDN上。

✓ 如果类型的实例很小并且通常生存时间较短,或者通常嵌入在其他对象中,则考虑定义结构体而不是类。

X 除非类型具有以下所有特征,否则避免定义结构体:

  • 它在逻辑上表示单个值,类似于基本类型(int、double等)。
  • 它的实例大小小于16字节。
  • 它是不可变的。
  • 它不需要经常装箱。

在所有其他情况下,应将类型定义为类。

相关信息:

何时使用结构体而不是类?


1
那只是一个经验法则。还有其他的,而且在我看来同样可信。请参阅比尔·瓦格纳(Bill Wagner)的《Effective C#》第2章,第18项,第104-110页!引用:“.NET文档建议您考虑类型的大小作为决定因素...实际上,一个更好的因素是类型的使用情况。” - TaW
我认为考虑大小限制是因为当结构体用作参数传递时,它们是按值传递的,当您有许多方法调用时,这可能会导致问题。@TaW - Hamid Pourjam

1
你应该避免使用结构体的默认相等性实现。如果你的结构体包含引用类型字段(如PersonStruct),则会使用反射来比较相应的字段是否相等,这相对较慢。你还应该为你的结构体实现IEquatable<T>,因为调用object.Equals(object)方法将导致源和参数结构体都装箱。如果调用可以解析为IEquatable<PersonStruct>,则可以避免这种情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接