MSDN说当需要轻量级对象时应该使用结构。在其他情况下,结构体比类更可取吗?

有些人可能已经忘记了:

结构可以有方法。 结构不能被继承。

我理解结构体和类之间的技术差异,我只是对什么时候使用结构体没有很好的感觉。


当前回答

✔️如果该类型的实例很小且通常存在时间很短,或者通常嵌入在其他对象中,请考虑定义一个结构而不是类。

其他回答

当您需要值类型语义而不是引用类型时,请使用结构。结构体是按值复制的,所以要小心!

另见以前的问题,例如:

.NET中struct和class的区别是什么?

MSDN给出了答案: 在类和结构之间选择。

基本上,这个页面给你一个4项清单,并告诉你使用一个类,除非你的类型满足所有的标准。

不定义结构,除非 类型包含以下所有内容 特点: 它在逻辑上表示一个值,类似于基本类型 (整数,双精度,等等)。 实例大小小于16字节。 它是不可变的。 它不需要经常装箱。

我认为最好的答案就是当你需要的是属性的集合时使用struct,当你需要的是属性和行为的集合时使用class。

我很惊讶我没有读到之前的答案,我认为这是最关键的方面:

当我想要一个没有标识的类型时,我使用结构体。例如一个3D点:

public struct ThreeDimensionalPoint
{
    public readonly int X, Y, Z;
    public ThreeDimensionalPoint(int x, int y, int z)
    {
        this.X = x;
        this.Y = y;
        this.Z = z;
    }

    public override string ToString()
    {
        return "(X=" + this.X + ", Y=" + this.Y + ", Z=" + this.Z + ")";
    }

    public override int GetHashCode()
    {
        return (this.X + 2) ^ (this.Y + 2) ^ (this.Z + 2);
    }

    public override bool Equals(object obj)
    {
        if (!(obj is ThreeDimensionalPoint))
            return false;
        ThreeDimensionalPoint other = (ThreeDimensionalPoint)obj;
        return this == other;
    }

    public static bool operator ==(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2)
    {
        return p1.X == p2.X && p1.Y == p2.Y && p1.Z == p2.Z;
    }

    public static bool operator !=(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2)
    {
        return !(p1 == p2);
    }
}

如果你有这个结构体的两个实例,你不关心它们是内存中的单个数据还是两个。你只关心他们持有的价值。

在以下情况下使用类:

它的身份很重要。结构在按值传递给方法时被隐式复制。 它将占用大量内存。 它的字段需要初始化式。 你需要从基类继承。 你需要多态行为;

在以下情况下使用结构:

It will act like a primitive type (int, long, byte, etc.). It must have a small memory footprint. You are calling a P/Invoke method that requires a structure to be passed in by value. You need to reduce the impact of garbage collection on application performance. Its fields need to be initialized only to their default values. This value would be zero for numeric types, false for Boolean types, and null for reference types. Note that in C# 6.0 structs can have a default constructor that can be used to initialize the struct’s fields to nondefault values. You do not need to inherit from a base class (other than ValueType, from which all structs inherit). You do not need polymorphic behavior.