338 Stimmen

Wann sollte ich eine Struktur anstelle einer Klasse verwenden?

MSDN sagt, dass Sie structs verwenden sollten, wenn Sie leichtgewichtige Objekte benötigen. Gibt es noch andere Szenarien, in denen eine Struktur einer Klasse vorzuziehen ist?

Manche Leute haben das vielleicht vergessen:

  1. Strukturen können Methoden haben.
  2. Strukturen kann nicht vererbt werden.

Ich verstehe die technischen Unterschiede zwischen Structs und Klassen, ich habe nur kein gutes Gefühl für wenn um eine Struktur zu verwenden.

320voto

OwenP Punkte 24128

MSDN hat die Antwort: Auswahl zwischen Klassen und Strukturen .

Diese Seite enthält eine Checkliste mit vier Punkten und empfiehlt die Verwendung einer Klasse, wenn Ihr Typ nicht alle Kriterien erfüllt.

Definieren Sie keine Struktur Typ hat alle der folgenden Eigenschaften:

  • Er stellt logischerweise einen einzelnen Wert dar, ähnlich wie bei primitiven Typen (Integer, Double und so weiter).
  • Sie hat eine Instanzgröße von weniger als 16 Byte.
  • Sie ist unveränderlich.
  • Es muss nicht häufig eingepackt werden.

58voto

Andrei Rînea Punkte 19502

Ich bin überrascht, dass ich bei keiner der bisherigen Antworten diesen, meiner Meinung nach wichtigsten Aspekt gelesen habe:

Ich verwende Structs, wenn ich einen Typ ohne Identität haben möchte. Zum Beispiel ein 3D-Punkt:

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

Wenn Sie zwei Instanzen dieser Struktur haben, ist es egal, ob es sich um ein einziges Datenstück im Speicher oder um zwei handelt. Sie interessieren sich nur für den Wert (die Werte), die sie enthalten.

32voto

Bart Gijssens Punkte 1532

Bill Wagner hat ein Kapitel darüber in seinem Buch "effective c#" ( http://www.amazon.com/Effective-Specific-Ways-Improve-Your/dp/0321245660 ). Er schließt mit folgendem Grundsatz:

  1. Liegt die Hauptverantwortung bei der Art der Datenspeicherung?
  2. Ist seine öffentliche Schnittstelle vollständig durch Eigenschaften definiert, die auf seine Datenelemente zugreifen oder diese verändern?
  3. Sind Sie sicher, dass Ihr Typ niemals Unterklassen haben wird?
  4. Sind Sie sicher, dass Ihr Typ niemals polymorph behandelt werden wird?

Wenn Sie alle 4 Fragen mit "Ja" beantworten: Verwenden Sie eine Struktur. Andernfalls verwenden Sie eine Klasse.

21voto

Verwenden Sie eine Klasse, wenn:

  • Ihre Identität ist wichtig. Strukturen werden implizit kopiert, wenn sie als Wert an eine Methode übergeben werden.
  • Es wird einen großen Speicherbedarf haben.
  • Seine Felder benötigen Initialisierungen.
  • Sie müssen von einer Basisklasse erben.
  • Sie brauchen polymorphes Verhalten;

Verwenden Sie eine Struktur, wenn:

  • Er verhält sich wie ein primitiver Typ (int, long, byte, etc.).
  • Sie muss einen geringen Speicherbedarf haben.
  • Sie rufen eine P/Invoke-Methode auf, die die Übergabe einer Struktur durch Wert.
  • Sie müssen die Auswirkungen der Garbage Collection auf die Anwendungsleistung reduzieren.
  • Seine Felder müssen nur mit ihren Standardwerten initialisiert werden. Dieser Wert wäre bei numerischen Typen null, bei booleschen Typen false und bei Referenztypen null.
    • Beachten Sie, dass Structs in C# 6.0 einen Standardkonstruktor haben können, der verwendet werden kann, um die Felder der Struktur zu initialisieren. Felder der Struktur auf Nicht-Standardwerte zu initialisieren.
  • Sie müssen nicht von einer Basisklasse erben (mit Ausnahme von ValueType, von dem alle structs erben).
  • Sie brauchen kein polymorphes Verhalten.

17voto

Simon Steele Punkte 11468

Verwenden Sie eine Struktur, wenn Sie eine wertartige Semantik anstelle einer referenzartigen wünschen. Structs sind Copy-by-Value, also seien Sie vorsichtig!

Siehe auch frühere Fragen, z. B.

Was ist der Unterschied zwischen struct und class in .NET?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X