Zunächst einmal sind die Antworten von Jon, Michael und Jared im Wesentlichen richtig, aber ich möchte noch ein paar Dinge hinzufügen.
Was ist mit einer "unreinen" Methode gemeint?
Es ist einfacher, reine Methoden zu charakterisieren. Eine "reine" Methode hat folgende Eigenschaften:
- Seine Ausgabe wird vollständig durch seine Eingabe bestimmt; Die Ausgabe hängt nicht von externen Faktoren wie der Tageszeit oder den Bits auf Ihrer Festplatte ab. Seine Ausgabe hängt nicht von seiner Geschichte ab; Das zweimalige Aufrufen der Methode mit einem bestimmten Argument sollte das gleiche Ergebnis liefern.
- Eine reine Methode erzeugt keine beobachtbaren Mutationen in der Welt um sie herum. Eine reine Methode kann sich aus Effizienzgründen dafür entscheiden, den privaten Staat zu mutieren, aber eine reine Methode mutiert beispielsweise nicht ein Feld ihrer Argumentation.
Zum Beispiel Math.Cos
ist eine reine Methode. Die Ausgabe hängt nur von der Eingabe ab, und die Eingabe wird durch den Aufruf nicht geändert.
Eine unreine Methode ist eine Methode, die nicht rein ist.
Was sind einige der Gefahren, wenn schreibgeschützte Strukturen an unreine Methoden übergeben werden?
Es gibt zwei, die mir in den Sinn kommen. Das erste ist das, auf das Jon, Michael und Jared hingewiesen haben, und das ist das, vor dem Resharper Sie warnt. Wenn Sie eine Methode für eine Struktur aufrufen, übergeben wir immer einen Verweis auf die Variable, die der Empfänger ist, falls die Methode die Variable mutieren möchte.
Was ist, wenn Sie eine solche Methode für einen Wert und nicht für eine Variable aufrufen? In diesem Fall erstellen wir eine temporäre Variable, kopieren den Wert hinein und übergeben einen Verweis auf die Variable.
Eine schreibgeschützte Variable wird als Wert betrachtet, da sie außerhalb des Konstruktors nicht mutiert werden kann. Wir kopieren die Variable also in eine andere Variable, und die unreine Methode mutiert möglicherweise die Kopie, wenn Sie beabsichtigen, die Variable zu mutieren.
Das ist die Gefahr, eine schreibgeschützte Struktur als Empfänger zu übergeben . Es besteht auch die Gefahr, dass eine Struktur übergeben wird, die ein schreibgeschütztes Feld enthält. Eine Struktur, die ein schreibgeschütztes Feld enthält, ist eine gängige Praxis, aber es wird im Wesentlichen ein Scheck ausgestellt, dass das Typsystem nicht über die Mittel verfügt, um Bargeld zu erhalten. Die "Nur-Lese-Fähigkeit" einer bestimmten Variablen wird vom Eigentümer des Speichers bestimmt. Eine Instanz eines Referenztyps "besitzt" ihren eigenen Speicher, eine Instanz eines Werttyps jedoch nicht!
struct S
{
private readonly int x;
public S(int x) { this.x = x; }
public void Badness(ref S s)
{
Console.WriteLine(this.x);
s = new S(this.x + 1);
// This should be the same, right?
Console.WriteLine(this.x);
}
}
Man glaubt, dass this.x
sich das nicht ändern wird, weil x ein schreibgeschütztes Feld und Badness
kein Konstruktor ist. Aber...
S s = new S(1);
s.Badness(ref s);
... zeigt deutlich die Falschheit davon. this
und s
verweisen auf dieselbe Variable, und diese Variable ist nicht schreibgeschützt!