2010-11-18 6 views
4

Ich möchte mit TypeBuilder einen Typ erstellen, der mit einer Schnittstelle übereinstimmt. Sein Basistyp ist ein Objekt, da ich keinen Abstraktionspunkt habe. soWenn ich mit TypeBuilder einen Typ mit einer Eigenschaft erstelle, muss ich einen propertyBuilder verwenden?

Die Schnittstelle in Frage hat eine Eigenschaft wie ::

public interface IFoo{ 
    int Property{get;} 
} 

Muss ich wirklich eine PropertyBuilder schaffen? Oder kann ich einfach eine Methode für die int get_Property() Methode emittieren?

+0

+1 Interessante Frage. Das einzige Mal, dass ich jemals einen Type dynamisch erstellt habe, habe ich nur öffentliche Felder verwendet, um nicht mit PropertyBuilders herumzuärgern. – BFree

Antwort

5

Die CLI nicht über Eigenschaften kümmern, solange alle Methoden (die wirklich definiert alle eine Schnittstelle) haben Implementierungen:

var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(
    new AssemblyName("foo"), AssemblyBuilderAccess.RunAndSave); 
var mb = ab.DefineDynamicModule("foo"); 
var tb = mb.DefineType("bar"); 
tb.AddInterfaceImplementation(typeof(IFoo)); 
var method = typeof(IFoo).GetProperty("Property").GetGetMethod(); 
var impl = tb.DefineMethod("impl", 
    MethodAttributes.Private | MethodAttributes.Virtual, 
    typeof(int), Type.EmptyTypes); 
var il = impl.GetILGenerator(); 
il.Emit(OpCodes.Ldc_I4_7); // because it is lucky 
il.Emit(OpCodes.Ret); 
tb.DefineMethodOverride(impl, method); 

var type = tb.CreateType(); 
IFoo foo = (IFoo)Activator.CreateInstance(type); 
var val = foo.Property; 
+0

Danke! Dadurch wird mein Duck Taper einfacher, aber warum machen Sie MethodOverride, wenn die Methode nicht wirklich auf dem Typ definiert wurde? –

+0

@Michael - weil Sie es so sagen, welche Methode die Implementierung bietet. Interface-Methoden sind technisch implizite virtuelle Methoden, wenn Sie sich die CLI-Flags ansehen. –

+0

ah cool. Wenn ich eine öffentliche virtuelle Methode namens get_Property deklariere, scheint es auch zu funktionieren. Ich denke, das ist erforderlich, wenn ich verschiedene Implementierungen für mehrere Schnittstellen hinzufügen möchte. –

0

Ich würde denken, dass Sie einen PropertyBuilder verwenden müssen - eine Eigenschaft in .Net ist nicht so einfach wie get_ und/oder set_ Methoden - es sind zusätzliche Metadaten erforderlich.

Ich habe noch nie TypeBuilder verwendet, aber ich würde ziemlich überrascht sein, wenn Sie damit kommen würden, nur eine get_-Methode auszugeben.

+0

Überraschend oder nicht, du * kannst * einfach eine get-Methode ausgeben - in der Tat muss es überhaupt nicht "get_" * sein. –

+0

Nun, ich habe heute etwas Neues gelernt. Kann ich etwas über CLI Kuriositäten nachlesen? – TheEvilPenguin

Verwandte Themen