2011-03-11 2 views
8

je tentais de définir un type à l'exécution qui hérite d'une classe connue et implémente une interface.Interface mise en œuvre lors de l'exécution: méthode get_Value pas mis en œuvre

public class ParentClass 
{ 
} 

public interface IImplementMe 
{ 
    double Value{get;set} 
} 

est ici l'extrait de code qui montre comment j'essaie d'atteindre mon objectif.

public class ClassBuilder 
    { 
    public Type Build() 
    { 
     try 
     { 
      AssemblyName assemblyName = new AssemblyName("DataBuilderAssembly"); 
      AssemblyBuilder assemBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); 
      ModuleBuilder moduleBuilder = assemBuilder.DefineDynamicModule("DataBuilderModule"); 
      TypeBuilder typeBuilder = moduleBuilder.DefineType("NewClass", TypeAttributes.Class, typeof(ParentClass)); 
      typeBuilder.AddInterfaceImplementation(typeof(IImplementMe)); 
      BuildProperty(typeBuilder, "Value", typeof(double)); 
      Type type = typeBuilder.CreateType(); 

      return type; 
     } 
     catch (Exception e) 
     { 
      return null; 
     } 

    } 

    private void BuildProperty(TypeBuilder typeBuilder, string name, Type type) 
    { 
     FieldBuilder field = typeBuilder.DefineField("m" + name, type, FieldAttributes.Private); 
     PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(name, PropertyAttributes.None, type, null); 

     MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.HideBySig; 

     MethodBuilder getter = typeBuilder.DefineMethod("get_" + name, getSetAttr, type, Type.EmptyTypes); 

     ILGenerator getIL = getter.GetILGenerator(); 
     getIL.Emit(OpCodes.Ldarg_0); 
     getIL.Emit(OpCodes.Ldfld, field); 
     getIL.Emit(OpCodes.Ret); 

     MethodBuilder setter = typeBuilder.DefineMethod("set_" + name, getSetAttr, null, new Type[] { type }); 

     ILGenerator setIL = setter.GetILGenerator(); 
     setIL.Emit(OpCodes.Ldarg_0); 
     setIL.Emit(OpCodes.Ldarg_1); 
     setIL.Emit(OpCodes.Stfld, field); 
     setIL.Emit(OpCodes.Ret); 


     propertyBuilder.SetGetMethod(getter); 
     propertyBuilder.SetSetMethod(setter); 
    } 
} 

Pour une raison quelconque, j'obtenir une « méthode get_Value pas mise en oeuvre » exception à appeler typeBuilder.CreateType(). Jusqu'à présent, incapable de voir la raison derrière cela.

Répondre

7

Changer votre ligne:

MethodAttributes getSetAttr = MethodAttributes.Public | 
    MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Virtual; 

Votre code a ensuite travaillé pour moi. (Le virtuel était nécessaire.)

+0

essayé d'ajouter « MethodAttributes.SpecialName », mais cela n'a pas aidé. :./ –

+0

@ L.E.O, j'ai essayé votre code moi-même, et il a bien fonctionné quand j'ajouté tous les attributs méthode je l'ai mentionné (virtuel semble avoir été nécessaire.) –

+0

Oui, merci, travaillé comme un charme. –

12

L'implémentation de l'interface C# implicite (par correspondance de nom) est de commodité; quand il fait à la main, vous devez associer chacun à la table méthode virtuelle en utilisant typeBuilder.DefineMethodOverride, en passant dans la nouvelle méthode (généré) et la méthode d'interface pour satisfaire. Cela doit être fait pour chaque méthode de chaque interface que vous souhaitez implémenter.

+0

C'est quelque chose dont je serai au courant. Merci. –