2011-02-11 8 views
5

मैं अपने पहले के प्रश्न पर निम्नलिखित हूं: Mono.Cecil: call base class' method from other assembly
मैं वही कर रहा हूं, लेकिन यदि मेरा बेस क्लास सामान्य है तो यह काम नहीं करता है।मोनो। सेसिल: अन्य असेंबली से जेनेरिक बेस क्लास 'विधि को कॉल करें

//in Assembly A 
class BaseVM<T> {} 

//in Assembly B 
class MyVM : Base<SomeModel> { 
[NotifyProperty] 
public string Something {get;set;} 
} 

यह निम्न कोड बुनती:

L_000e: call instance void [AssemblyA]Base`1<class SomeModel>::RaisePropertyChanged(string) 

की

L_000e: call instance void [AssemblyA]Base`1::RaisePropertyChanged(string) 

बजाय क्या है परिवर्तित करने के लिए?

+0

इस बल्कि महत्वपूर्ण हो रही है

चीजों को आसान बनाने के लिए, के लिए निम्न विधियों, सेसिल टेस्ट स्वीट से लिया का उपयोग करते हैं कृपया सहायता कीजिए!!! – TDaver

उत्तर

16

अपने पिछले पोस्ट में आप संकेत मिलता है कि आप की तरह कोड का उपयोग कर रहे:

TypeDefinition type = ...; 
TypeDefintion baseType = type.BaseType.Resolve(); 
MethodDefinition baseMethod = baseType.Methods.First (m => ...); 
MethodReference baseMethodReference = type.Module.Import (baseMethod); 
il.Emit (OpCodes.Call, baseMethodReference); 

जाहिर है, इस जेनरिक लिए उपयुक्त नहीं है:

जब आप Resolve() .BaseType, तो आप खो रहे हैं सामान्य तत्काल जानकारी। आपको बेस टाइप से उचित जेनेरिक जानकारी के साथ उपयुक्त विधि कॉल को फिर से बनाना होगा। , आप के रूप में अपने कोड को फिर से लिखने कर सकते हैं

public static TypeReference MakeGenericType (this TypeReference self, params TypeReference [] arguments) 
{ 
    if (self.GenericParameters.Count != arguments.Length) 
     throw new ArgumentException(); 

    var instance = new GenericInstanceType (self); 
    foreach (var argument in arguments) 
     instance.GenericArguments.Add (argument); 

    return instance; 
} 

public static MethodReference MakeGeneric (this MethodReference self, params TypeReference [] arguments) 
{ 
    var reference = new MethodReference(self.Name,self.ReturnType) { 
     DeclaringType = self.DeclaringType.MakeGenericType (arguments), 
     HasThis = self.HasThis, 
     ExplicitThis = self.ExplicitThis, 
     CallingConvention = self.CallingConvention, 
    }; 

    foreach (var parameter in self.Parameters) 
     reference.Parameters.Add (new ParameterDefinition (parameter.ParameterType)); 

    foreach (var generic_parameter in self.GenericParameters) 
     reference.GenericParameters.Add (new GenericParameter (generic_parameter.Name, reference)); 

    return reference; 
} 
उन के साथ

:,

TypeDefinition type = ...; 
TypeDefintion baseTypeDefinition = type.BaseType.Resolve(); 
MethodDefinition baseMethodDefinition = baseTypeDefinition.Methods.First (m => ...); 
MethodReference baseMethodReference = type.Module.Import (baseMethodDefinition); 
if (type.BaseType.IsGenericInstance) { 
    var baseTypeInstance = (GenericInstanceType) type.BaseType; 
    baseMethodReference = baseMethodReference.MakeGeneric (baseTypeInstance.GenericArguments.ToArray()); 
} 

il.Emit (OpCodes.Call, baseMethodReference); 
+0

धन्यवाद, यह काम कर रहा है! – TDaver

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