Frage

Ich habe alle Fragen zu diesem Thema gelesen und alle geben Gründe an, warum ein Standardkonstruktor auf a struct ist in C#nicht verfügbar, aber ich habe noch niemanden gefunden, der eine allgemeine Vorgehensweise vorschlägt, wenn ich mit dieser Situation konfrontiert wird.

Die offensichtliche Lösung besteht darin, die einfach umzuwandeln struct zu einem class und mit den Konsequenzen umgehen.

Gibt es andere Optionen, um es als struct?

Ich bin mit einem unserer internen API -Objekte in dieser Situation gestoßen. Der Designer hat es von a umgewandelt class zu einem struct, und jetzt verlässt der Standardkonstruktor (der zuvor privat war) das Objekt in einem ungültigen Zustand.

Ich dachte, wenn wir das Objekt als behalten wollen struct, ein Mechanismus zur Überprüfung der Gültigkeit des Staates sollte eingeführt werden (so etwas wie eine IsValid Eigentum). Ich war mit viel Widerstand gestoßen, und eine Erklärung von "Wer auch immer die API verwendet, sollte den Standardkonstruktor nicht verwenden", ein Kommentar, der meine Augenbrauen sicherlich hob. (Hinweis: Das fragliche Objekt wird "richtig" durch statische Fabrikmethoden konstruiert, und alle anderen Konstrukteure sind internal.)

Konvertiert jeder einfach seine structs zu classes in dieser Situation ohne einen zweiten Gedanken?

Bearbeiten: Ich würde gerne einige Vorschläge darüber sehen struct - Das obige Objekt oben ist viel besser geeignet als struct als als a class.

War es hilfreich?

Lösung

Für ein struct, Sie entwerfen den Typ, sodass die Standardinstanz (Fields All Null) ein gültiger Zustand ist. Du nicht [soll nicht] willkürlich verwenden struct Anstatt von class Ohne einen guten Grund - es ist nichts Falsches daran, einen unveränderlichen Referenztyp zu verwenden.

Meine Vorschläge:

  • Stellen Sie sicher, dass der Grund für die Verwendung von a struct ist gültig (ein [real] Profiler hat signifikante Leistungsprobleme enthüllt, die sich aus einer starken Allokation eines sehr leichten Objekts ergeben).
  • Entwerfen Sie den Typ, sodass die Standard -konstruierte Instanz gültig ist.
  • Wenn das Design des Typs durch native/com -Interop -Einschränkungen diktiert wird, wickeln Sie die Funktionalität ein und legen Sie die nicht frei struct außerhalb der Wrapper (privat verschachtelter Typ). Auf diese Weise können Sie die ordnungsgemäße Verwendung der eingeschränkten Typanforderungen leicht dokumentieren und überprüfen.

Andere Tipps

Der Grund dafür ist, dass eine Struktur (eine Instanz von System.Valuetype) speziell von der CLR behandelt wird: Sie wird mit allen Feldern initialisiert, die 0 (oder Standard) sind. Sie müssen nicht einmal einen erstellen - deklarieren Sie es einfach. Aus diesem Grund sind Standardkonstruktoren erforderlich.

Sie können dies auf zwei Arten umgehen:

  1. Erstellen Sie eine Eigenschaft wie Isvalid, um anzuzeigen, ob es sich um eine gültige Struktur handelt, wie Sie angeben und
  2. In .NET 2.0 überlegen Sie nullierbaru003CT> eine nicht initialisierte (NULL) Struktur zuzulassen.

Das Ändern der Struktur in eine Klasse kann einige sehr subtile Konsequenzen haben (in Bezug auf Speicherverbrauch und Objektidentität, die in einer Multithread-Umgebung mehr auftreten) und nicht so subtil, aber schwer zu debuggen NullReferencexceptions für nicht initialisierte Objekte.

Der Grund, warum es keine Möglichkeit gibt, einen Standardkonstruktor zu definieren, wird durch den folgenden Ausdruck dargestellt:

new MyStruct[1000];

Sie haben hier 3 Optionen

  1. Aufrufen des Standardkonstruktors 1000 -mal oder
  2. Erstellen von korrupten Daten (beachten Sie, dass eine Struktur Referenzen enthalten kann. Wenn Sie die Referenz nicht initialisieren oder leer haben, können Sie möglicherweise auf beliebige Speicher zugreifen) oder
  3. leer das zugewiesene Speicher mit Nullen (auf Byte -Ebene).

.NET tut dasselbe für Strukturen und Klassen: Felder und Array -Elemente werden mit Nullen ausgeblendet. Dies wird auch konsistenteres Verhalten zwischen Strukturen und Klassen und keinen unsicheren Code. Es ermöglicht dem .NET -Framework auch, etwas zu spezialisieren new byte[1000].

Und das ist der Standardkonstruktor für Strukturen .NET fordert und kümmert sich für sich selbst: Null alle Bytes.

Um damit umzugehen, haben Sie ein paar Optionen:

  • Fügen Sie der Struktur eine am-i-initialisierte Eigenschaft hinzu (wie wie HasValue an Nullable).
  • Lassen Sie die Null -Out -Struktur ein gültiger Wert sein (wie 0 ist ein gültiger Wert für eine Dezimalzahl).
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top