In .net, eine Struktur Instanzmethode ist semantisch äquivalent zu einer statischen Struktur Methode mit einem extra ref
Parameter der Struktur Art. Somit wird die Erklärungen gegeben:
struct Blah {
public int value;
public void Add(int Amount) { value += Amount; }
public static void Add(ref Blah it; int Amount; it.value += Amount;}
}
Die Methode ruft:
someBlah.Add(5);
Blah.Add(ref someBlah, 5);
sind semantisch äquivalent, mit Ausnahme von einem Unterschied: die letztere Anruf wird nur dann zugelassen werden, wenn someBlah
eine veränderbare Speicherstelle (variable, Feld usw.) und nicht, wenn es sich um einen Nur-Lese-Speicherort oder um einen temporären Wert handelt (Ergebnis des Lesens einer Eigenschaft usw.).
Dies stellte die Designer von .net-Sprachen mit einem Problem konfrontiert: die Verwendung von Member-Funktionen in schreibgeschützten Strukturen zu verbieten wäre ärgerlich, aber sie wollten nicht zulassen, dass Member-Funktionen auf schreibgeschützte Variablen schreiben. Sie entschieden sich für "punt" und machen es so, dass das Aufrufen einer Instanzmethode für eine schreibgeschützte Struktur eine Kopie der Struktur erstellt, die Funktion darauf aufruft und sie dann verwirft. Dies hat zur Folge, dass Aufrufe von Instanzmethoden, die die zugrunde liegende Struktur nicht schreiben, verlangsamt werden und dass der Versuch, eine Methode zu verwenden, die die zugrundeliegende Struktur in einer schreibgeschützten Struktur aktualisiert, verschiedene gebrochene Semantiken ergibt von was würde erreicht werden, wenn es die Struktur direkt übergeben würde. Beachten Sie, dass die zusätzliche Zeit, die die Kopie benötigt, in Fällen, die ohne die Kopie nicht korrekt gewesen wären, fast nie eine korrekte Semantik ergibt.
Einer meiner wichtigsten peeves in .net ist, dass es immer noch (seit mindestens 4.0 und wahrscheinlich 4.5) immer noch kein Attribut gibt, über das eine Strukturelementfunktion angeben kann, ob es this
ändert.Leute schildern, wie Strukturen unveränderlich sein sollten, anstatt die Werkzeuge bereitzustellen, die es Strukturen erlauben, Mutationsmethoden sicher anzubieten. Dies trotz der Tatsache, dass sogenannte "unveränderliche" Strukturen eine Lüge sind. Alle nicht-trivialen Werttypen in veränderbaren Speicherorten sind veränderbar, ebenso wie alle eingerahmten Werttypen. Eine Struktur "unveränderlich" zu machen, kann einen dazu zwingen, eine ganze Struktur umzuschreiben, wenn man nur ein Feld ändern will, aber seit struct1 = struct2
muate struct1 durch Kopieren aller öffentlichen Felder und private von struct2, und es gibt nichts die Typdefinition für die Struktur tun können, um dies zu verhindern (außer keine Felder zu haben), tut es nichts, um eine unerwartete Mutation von Strukturelementen zu verhindern. Darüber hinaus sind Strukturen aufgrund von Threading-Problemen sehr eingeschränkt in ihrer Fähigkeit, jede Art von invarianter Beziehung zwischen ihren Feldern zu erzwingen. IMHO, es wäre im Allgemeinen besser für eine Struktur mit willkürlichen Feldzugriff zu ermöglichen, klar, dass jeder Code erhalten eine Struktur muss überprüfen, ob seine Felder alle erforderlichen Bedingungen erfüllen, als versuchen, die Bildung von Strukturen, die Bedingungen nicht erfüllen zu verhindern.
Siehe Eric Lippert ["Mutating Readonly Structs"] (http://blogs.msdn.com/b/ericlippert/archive/2008/05/14/mutating-readonly-structs.aspx) –
* Warum * würden Sie erwarte zwei 1s? Du hast gesagt, du wolltest, dass es nur gelesen wird, also warum willst du, dass es sich ändert? –