2011-03-11 17 views
8

Bilinen bir sınıftan miras alan ve bir arabirim uygulayan çalışma zamanında bir tür tanımlamaya çalışıyordum.Çalışma zamanında uygulama arabirimi: get_Value yöntemi uygulanmadı

public class ParentClass 
{ 
} 

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

Hedefime nasıl ulaşmaya çalıştığımı gösteren kod parçacığı İşte.

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); 
    } 
} 

Nedense ben bir typeBuilder.CreateType() çağırmayı istisna "get_Value yöntemi uygulanmadı" olsun. Şimdiye kadar arkasındaki sebebi göremedi.

cevap

7

hattınızı değiştirme:

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

Kodunuz sonra benim için çalıştı. (Sanal gerekliydi.)

+0

'MethodAttributes.SpecialName' ekledim, ancak bu yardımcı olmadı. :/ –

+0

@ L.E.O. Kodunuzu kendim denedim ve bahsettiğim tüm metod özelliklerini eklediğimde gayet iyi çalıştı (sanal gerekli göründü.) –

+0

Evet, teşekkürler, bir cazibe gibi çalıştı. –

12

C# örtük arabirim uygulaması (ad eşleşmesiyle) yalnızca kolaylık; el ile bunu yaparken, yeni (üretilen) yöntemi ve tatmin etmek için arabirim yöntemini geçerek, typeBuilder.DefineMethodOverride'ı kullanarak sanal yöntem tablosunda her birini ilişkilendirmeniz gerekir. Bu, uygulamak istediğiniz her arayüzün her yöntemi için yapılmalıdır.

+0

Bu, bileceğim bir şey. Teşekkürler. –

İlgili konular