When should I use a struct instead of a class?

2018-12-31 14:06发布

MSDN says that you should use structs when you need lightweight objects. Are there any other scenarios when a struct is preferable over a class?

Some people might have forgotten that:

  1. structs can have methods.
  2. structs cannot be inherited.

I understand the technical differences between structs and classes, I just don't have a good feel for when to use a struct.

标签: .net oop
14条回答
栀子花@的思念
2楼-- · 2018-12-31 14:33

Structs are on the Stack not the Heap so therefore they are thread safe, and should be used when implementing the transfer object pattern, you never want to use objects on the Heap they are volatile, you want in this case to use the Call Stack, this is a basic case for using a struct I am surprised by all the way out answers here,

查看更多
梦醉为红颜
3楼-- · 2018-12-31 14:34

MSDN has the answer: Choosing Between Classes and Structures.

Basically, that page gives you a 4-item checklist and says to use a class unless your type meets all of the criteria.

Do not define a structure unless the type has all of the following characteristics:

  • It logically represents a single value, similar to primitive types (integer, double, and so on).
  • It has an instance size smaller than 16 bytes.
  • It is immutable.
  • It will not have to be boxed frequently.
查看更多
怪性笑人.
4楼-- · 2018-12-31 14:35

I am surprised I have not read at any of the previous answer this, which I consider the most crucial aspect :

I use structs when I want a type with no identity. For example a 3D point:

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);
    }
}

If you have two instances of this struct you don't care if they are a single piece of data in memory or two. You just care about the value(s) they hold.

查看更多
听够珍惜
5楼-- · 2018-12-31 14:36

Use a class if:

  • Its identity is important. Structures get copied implicitly when being passed by value into a method.
  • It will have a large memory footprint.
  • Its fields need initializers.
  • You need to inherit from a base class.
  • You need polymorphic behavior;

Use a structure if:

  • 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.
查看更多
旧人旧事旧时光
6楼-- · 2018-12-31 14:36

when you don't really need behavior, but you need more structure than a simple array or dictionary.

Follow up This is how I think of structs in general. I know they can have methods, but I like keeping that overall mental distinction.

查看更多
闭嘴吧你
7楼-- · 2018-12-31 14:38

Bill Wagner has a chapter about this in his book "effective c#" (http://www.amazon.com/Effective-Specific-Ways-Improve-Your/dp/0321245660). He concludes by using the following principle:

  1. Is the main responsability of the type data storage?
  2. Is its public interface defined entirely by properties that access or modify its data members?
  3. Are you sure your type will never have subclasses?
  4. Are you sure your type will never be treated polymorphically?

If you answer 'yes' to all 4 questions: use a struct. Otherwise, use a class.

查看更多
登录 后发表回答