Kann ich ein privates Readonly-Feld in C # mithilfe von Reflektion ändern?
Frage ich mich, da viele Dinge, die getan werden kann, mit der spiegelung, kann ich eine private readonly-Feld nach dem Konstruktor beendet seine Ausführung?
(Hinweis: nur Neugierde)
public class Foo
{
private readonly int bar;
public Foo(int num)
{
bar = num;
}
public int GetBar()
{
return bar;
}
}
Foo foo = new Foo(123);
Console.WriteLine(foo.GetBar()); //display 123
//reflection code here...
Console.WriteLine(foo.GetBar()); //display 456
InformationsquelleAutor der Frage Ron Klein | 2009-06-01
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie:
InformationsquelleAutor der Antwort Philippe Leybaert
Die offensichtliche Sache ist, es zu versuchen:
Diese funktioniert einwandfrei. (Java hat andere Regeln, interessant - Sie haben explizit den
Field
zugänglich zu sein, und es wird nur funktionieren, z.B. Felder sowieso.)InformationsquelleAutor der Antwort Jon Skeet
Ich Stimme mit den anderen Antworten, dass es funktioniert in der Regel und vor allem mit dem Kommentar von E. Lippert, dieses nicht dokumentierte Verhalten und daher nicht zukunftssicher code.
Aber wir bemerkten auch ein weiteres Problem. Wenn Sie Ihren code ausführen in einer Umgebung mit eingeschränkten Berechtigungen erhalten Sie möglicherweise eine Ausnahme.
Wir hatten gerade einen Fall, wo unser code war in Ordnung, auf unsere Maschinen, aber wir erhielten eine
VerificationException
wenn der code lief in einer geschützten Umgebung. Der Täter war ein Spiegelbild Aufruf der setter ein readonly-Feld. Es funktioniert, wenn wir entfernt die readonly-Einschränkung des Feldes.InformationsquelleAutor der Antwort Andreas
Fragte Sie, warum Sie möchten, um ein durchbrechen der Kapselung so.
Benutze ich ein Unternehmen helper-Klasse, um das Hydrat Personen. Diese verwendet reflektion, um alle Eigenschaften einer neuen, leeren Einheit, und stimmt mit der Eigenschaft/Feldname der Spalte in der Ergebnismenge, und legen Sie es mit propertyinfo.setvalue().
Ich möchte nicht, dass jemand werden in der Lage, um den Wert zu ändern, aber ich will nicht zu nehmen Sie alle Anstrengungen, um benutzerdefinierte code Hydratation Methoden für jede Entität entweder.
Meine viele meine gespeicherte Prozeduren Ergebnismengen abgerufen werden, entsprechen nicht direkt auf Tabellen oder sichten aus, so dass der code gen ORM ' s nichts zu tun für mich.
InformationsquelleAutor der Antwort Necroposter
Die Antwort ist ja, aber noch wichtiger ist:
Warum würden Sie wollen? Absichtlich brechen Kapselung scheint wie eine entsetzlich schlechte Idee zu mir.
Mithilfe der Reflexion zu ändern, eine readonly-Konstante oder-Feld ist wie die Kombination der Gesetz der Unbeabsichtigten Folgen mit Murphy ' s Law.
InformationsquelleAutor der Antwort Powerlord
Tun das nicht.
Verbrachte ich nur einen Tag die Festsetzung einer surrealen bug, wo Objekte werden könnte, nicht der eigenen deklarierten Typ.
Ändern Sie die readonly-Bereich mal gearbeitet. Aber wenn Sie versucht, es zu ändern wieder, Sie würden sich Situationen wie diese:
Also tun Sie es nicht.
Wurde diese auf der Mono-Laufzeitumgebung (Unity-game-engine).
InformationsquelleAutor der Antwort Tynan Sylvester
Eine weitere einfache Möglichkeit, dies zu tun mit unsicheren (oder Sie passieren konnten, das Feld zu einer C Methode über DLLImport und legen Sie es dort).
InformationsquelleAutor der Antwort zezba9000
Ich möchte nur hinzufügen, dass wenn Sie tun müssen, um dieses Zeug für unit-Tests, dann können Sie verwenden:
A) Die PrivateObject Klasse
B) Sie müssen noch ein PrivateObject Beispiel, aber Sie erzeugen kann "Accessor" - Objekte mit Visual Studio. Gewusst wie: Regenerieren Private Accessoren
Wenn Sie private Felder eines Objekts in Ihrem code außerhalb von unit-Tests, das wäre eine Instanz von "code smell" ich denke, dass vielleicht die einzige andere Grund würden Sie wollen, dies zu tun ist, wenn Sie es mit einem Drittanbieter-Bibliothek und Sie können nicht ändern die Ziel-Klasse code. Sogar dann, werden Sie wahrscheinlich wollen, um Kontakt mit dem 3rd-party, Ihre situation zu erklären und sehen, wenn Sie nicht gehen Sie vor und ändern Sie Ihren code zu empfangen, die Ihr braucht.
InformationsquelleAutor der Antwort Dudeman3000