2011-03-11 8 views
8

मैं एक ज्ञात वर्ग से प्राप्त होने वाले रन-टाइम पर एक प्रकार को परिभाषित करने और एक इंटरफ़ेस लागू करने की कोशिश कर रहा था।रन-टाइम पर इंटरफ़ेस कार्यान्वित करना: get_Value विधि लागू नहीं की गई

public class ParentClass 
{ 
} 

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

यहां कोड स्निपेट है जो दिखाता है कि मैं अपना लक्ष्य कैसे प्राप्त करने का प्रयास करता हूं।

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

किसी कारण से मैं एक typeBuilder.CreateType() बुला पर अपवाद "get_Value विधि लागू नहीं की" मिलता है। अब तक इसके कारण को देखने में असमर्थ।

उत्तर

7

करने के लिए अपने लाइन बदलने:

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

आपका कोड तो मेरे लिए काम किया। (आभासी आवश्यक था।)

+0

'MethodAttributes.SpecialName' जोड़ने का प्रयास किया, लेकिन इससे मदद नहीं मिली। :/ –

+0

@ एल.ई.ओ., मैंने आपके कोड को स्वयं करने की कोशिश की, और जब मैंने उल्लेख किया कि सभी विधि विशेषताओं को जोड़ा गया है (वर्चुअल प्रतीत होता है।) –

+0

हाँ, धन्यवाद, एक आकर्षण की तरह काम किया। –

12

सी # निहित इंटरफ़ेस कार्यान्वयन (नाम मिलान द्वारा) केवल सुविधा है; हाथ से ऐसा करते समय आपको प्रत्येक (जेनरेटेड) विधि में गुज़रने और संतुष्ट करने के लिए इंटरफ़ेस विधि में टाइप करने वाले टाइपबिल्डर। डीफिनमेथऑवरराइड का उपयोग करके वर्चुअल-विधि तालिका में प्रत्येक को जोड़ने की आवश्यकता होती है। यह प्रत्येक इंटरफ़ेस की प्रत्येक विधि के लिए किया जाना चाहिए जिसे आप कार्यान्वित करना चाहते हैं।

+0

ऐसा कुछ है जो मुझे पता होगा। धन्यवाद। –

संबंधित मुद्दे