2013-02-06 15 views
8

Ich habe eine Klasse:Wie kann ich einer Klasse zur Laufzeit in C# Eigenschaften hinzufügen?

class MyClass 
{ 
} 
... 
MyClass c = new MyClass(); 

Ist es möglich, Eigenschaften/Felder zu dieser Klasse auf der Laufzeit hinzufügen?

(Ich weiß nicht, was sind ihre Typen oder Namen auf Compile-Zeit und sie haben keine gemeinsame Schnittstelle, die ich verwenden kann.)

psuedo Beispiel:

Add property named "Prop1" [type System.Int32] 
Add property named "Prop900" [type System.String] 

Ich lese bereits this question, aber es verwendet die Schnittstelle

Vielen Dank im Voraus.

+2

Und dann Zugriff durch Reflexion überall? Wie wäre es mit einem 'Dictionary '? –

+0

@HenkHolterman Ja Henk Später greife ich auf sie mit 'MyClass.GetType(). GetProperties()' –

+1

Welchen Anwendungsfall benötigen Sie es? Was ist mit 'ICustomeTypeDescriptor'? – Dennis

Antwort

24

Sie können eine vorhandene Klasse zur Laufzeit nicht durch neue Member erweitern. Sie können jedoch eine neue Klasse mit System.Reflection.Emit erstellen, die die vorhandene Klasse als Basisklasse hat.

typeBuilder.SetParent(typeof(MyClass)); 
typeBuilder.DefineProperty("Prop1", ..., typeof(System.Int32), null); 
... 

Ein vollständiges Beispiel finden Sie unter TypeBuilder.DefineProperty Method (String, PropertyAttributes, Type, Type[]).

+0

Sieht interessant aus. Ich werde es mir mal ansehen. –

+0

Ich habe es geschafft. Vielen Dank. (das war der Weg). Danke für die Antwort auf die eigentliche Frage. –

+0

Schöne Erklärung, es hat auch für mich funktioniert .. –

1

Ja, Sie können die Klasse ExpandoObject verwenden, um dies zu erreichen.

dynamic expando = new ExpandoObject(); 
expando.Prop1 = 10; 
expando.Prop900 = string.Empty; 
+1

es verwendet Wörterbuchimplementierung innerhalb. Ich brauche eine reine Klasse mit Eigenschaften. –

+1

@RoyiNamir: Warum? –

+0

'GetType(). GetProperties()' ist wahrscheinlich weniger effizient als ein Dictionary. –

4

Ich denke, Sie haben missverstanden, was Reflexion ist. Mit Reflection können Sie den ausgeführten Code nicht ändern. Es kann Ihnen erlauben, Ihren eigenen Code zu lesen und sogar diesen Code auszuführen.

Mit Reflection.Emit können Sie eine ganze neue Assembly schreiben und dann in den Speicher laden.

Sie können jedoch keine Klasse zur Laufzeit ändern. Stellen Sie sich vor, Sie haben eine Klasse Foo, Sie setzen eine ganze Reihe von ihnen ein und entscheiden dann, die Klasse zu wechseln.

Was soll mit all den Foos geschehen, die Sie bereits installiert haben?

Aber was Sie tun können, verwenden Sie Reflection.Emit, um eine neue Klasse zu erstellen, die Foo erbt, genannt Bar, und fügen Sie dann alles, was Sie zu dieser Klasse benötigen.

Alternativ können Sie IL Weaving/AOP anzeigen, wenn Sie programmgesteuert eine Eigenschaft NACH der Kompilierzeit, aber VOR der Laufzeit einer Klasse hinzufügen möchten. Ich schlage vor, PostSharp oder Fody zu betrachten, wenn Sie interessiert sind.

Verwandte Themen