Dynamisch erzeugen-Eigenschaft getter - /setter-durch Reflexion oder ähnliches
Stellen Sie sich die folgende Klasse:
public class Settings
{
[FileBackedProperty("foo.txt")]
public string Foo { get; set; }
}
Ich würde gerne in der Lage sein, etwas zu schreiben, ähnlich wie die oben genannten und haben settings.Foo
aus der Datei Lesen "foo.txt" und settings.Foo = "bar"
schreiben "foo.txt".
Offensichtlich dies ist ein Vereinfachtes Beispiel und ich würde es nicht tun, die oben in einer Produktion, die Anwendung, aber es gibt auch andere Beispiele, wie, wenn ich wollte, Foo abgelegt werden ASP.net Session state "foo", aber ich müde von dem schreiben der folgende code immer und immer wieder:
public int Foo
{
get
{
if (Session["foo"] != null)
return Convert.ToInt32(Session["foo"]);
else
//Throw an exception or return a default value
}
set
{
Session["foo"] = value;
}
}
(Mal wieder das Beispiel ist vereinfacht, und ich würde nicht schreiben Sie den obigen code, eigentlich bin ich liegen, habe ich den obigen code und arbeite umgestalten, daher diese Frage)
Obigen Beispiel ist in Ordnung, es sei denn, Sie haben 50 verschiedene session-Werte, die alle haben ähnliche Logik. So ist es irgendwie, ich könnte konvertieren, die zweite Eigenschaft in etwas ähnlich wie die erste? (Verwendung von Attributen und Reflexion, oder vielleicht eine andere Methode?)
- Wenn Sie mithilfe von Visual Studio sollten Sie einen Blick auf " code-snippets. Sie ermöglichen es, etwas kurze, erweitern Sie den gewünschten code und dann können Sie zu füllen-in den angegebenen Bereichen. Ähnlich der bestehenden propg, etc.
- Das scheint nur so schlecht, wie copy/paste. Was ist, wenn ich ändern möchten die Umsetzung? Ich habe immer noch zurück zu gehen und ändern Sie jede Eigenschaft einzeln an.
- So dass Sie wollen, um dynamisch hinzufügen von Eigenschaften zur Laufzeit? Sie haben alle server-Maschinen oder niedrige Erwartungen an Leistung? Nicht, dass du das nicht so, aber ich würde stark Vorsicht gegen ihn. Wenn Sie nicht, dass zur Laufzeit, dann würden Sie haben, sich zu regenerieren jeder code, den Ausgang sowieso.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich weiß, das ist nicht das, was Sie (und auch ich), die benötigt werden; aber dies ist die nächste, ohne die Verwendung einer Drittanbieter-Bibliothek. Sie können ändern Sie die Logik für get&set-Methoden und fügen Sie einige cahcing für die GetProperty-und GetCustomAttributes-Methoden oder-wenn Sie bereits eine Basisklasse, die Sie schreiben können, get&set-Methoden als static in eine helper-Klasse. Wieder nicht die perfekte Antwort und kann auch eine schlechte Leistung, aber zumindest verringert es den code, den Sie kopieren und einfügen (:
HINWEIS: Es ist wichtig, um die Eigenschaften der virtuellen, um zu verhindern, compiler inlining Sie.
Eine weitere option könnte sein, für Sie ist die Verwendung von PostSharp.
Sie definieren Attribute, und es spritzt ein
IL
final code, so wird es nicht ändern Sie Ihren source-code. Das hat seine schlechten und seine waren.Dieses Produkt ist nicht frei.
Einige Erste Schritte Tipps.
Hoffe, das hilft.
IL
ist, dass zur compile-Zeit oder Start der Anwendung Zeit-oder was? Ich vermute, dass PostSharp dann bekommt rund um die performance-Probleme, dass AOP mit ContextBoundObject hat?Wenn Sie schauen, um dies zur Laufzeit finden Sie in der folgenden Dr. Dobbs Artikel Code-Generierung zur Laufzeit Mit Reflection.Emittieren.
Was Sie versuchen zu tun, ist genannt "Aspekt-Orientierte Programmierung" und es ist relativ üblich, bestimmte Aufgaben, bei denen die notwendigen code-ansonsten dupliziert werden oft mit nur sehr geringfügige änderungen. Dein Beispiel sicher qualifiziert.
Die grundlegende Idee ist wie folgt: Sie erstellen ein Attribut, das Sie verwenden können, zu schmücken, Klassen oder Schüler. Das Attribut definiert den "Kontext" für die eine message-passing-system in der CLR, können Sie Haken eine interceptor-Methode auf die Methode, die ausgeführt wird, wenn es aufgerufen wird.
Verstehen, dass es eine deutliche performance-Treffer beteiligt, das Objekt mit Elementen dekoriert, die durch Attribute müssen Erben von MarshallByRefObject oder ContextBoundObject; entweder einer von diesen entstehen, werden über einen 10-Fach Treffer, um die Leistung der das Objekt während der Laufzeit, auch wenn Sie nicht wirklich tun, jedes Attribut schmücken.
Hier einige Beispiel-code: http://www.developerfusion.com/article/5307/aspect-oriented-programming-using-net/3/
Können Sie auch Dynamische Proxys erstellen von Objekten "on the fly" basierend auf Attribut-Dekoration oder andere Reflexion-basierten Informationen. Dies ist die Technologie, die hinter vielen Sachen C# - Entwickler für selbstverständlich halten, wie ORMs, IoC-frameworks, etc etc. Sie würde im Grunde so etwas wie Schloss DynamicProxy ein Objekt zu erstellen, das aussah, wie Ihre Basis-Objekt, hatte aber überschrieben Definitionen der Eigenschaften geschmückt mit den Attributen, die eine Datei-basierte Bevölkerung/Persistenz-Logik.
Wenn Sie möchten, vermeiden Sie das schreiben der getter-code so viel, schreiben Sie eine helper-Methode:
Wenn Sie Zugriff auf Dynamik, dann können Sie ein dynamisches Objekt zu umbrechen der Sitzung:
Und Sie können dann verwenden Sie es wie so:
Letzte option ist so etwas wie Live-Vorlagen in Resharper um nur das eingeben des Codes viel einfacher.
Können Sie auch die DynamicProxy nuget-Paket von der Burg.Kern um dies zu erreichen Verhalten.
Können Sie abfangen Aufrufe von Get-und Set-Methoden für alle virtuellen Eigenschaften Ihrer Klasse. Haben aber alle die Eigenschaft Getter und setter, die Sie ändern möchten, müssen virtuell sein.
Habe ich eine vollständige Antwort hier:
https://stackoverflow.com/a/48764825/5103354
und eine Zusammenfassung ist verfügbar hier.
Folgendes Verhalten beobachtet werden:
Hoffe, das hilft.