2011-05-03 30 views
7

पर कास्ट पैरामीटर मैं किसी विशिष्ट प्रकार का एक विशिष्ट गुण के लिए गेटर फ़ंक्शन "लपेटना" चाहता हूं। मैं एक अमूर्त वर्ग, जैसे परिभाषित किया गया है निम्नलिखित:लैम्ब्डा अभिव्यक्ति: आधार प्रकार

public abstract class MyConcreteClass : MyAbstractClass<MyConcreteType> 
{ 
    // ... 
} 

और अब, सहायक विधि है कि एक आवरण लौटना चाहिए:

public abstract class MyAbstractClass<T> where T : MyType 
{ 
    // ... 
} 

ठीक है, मैं के बाद एक तरह एक ठोस वर्ग है लगता है

private Func<MyAbstractClass<T>, Object> GetPropertyGetter(PropertyInfo property) 
{ 
    var instanceType = Expression.Parameter(property.DeclaringType, "i"); 

    // Taking getter's "body". 
    var getterBody = Expression.Property(instanceType, property); 

    // Cast to a generic Object. 
    var body = Expression.TypeAs(getterBody, typeof(Object)); 

    // Build the expression. 
    var exp = Expression.Lambda<Func<MyAbstractClass<T>, Object>>(body, instanceType); 
    return exp.Compile(); 
} 

की उम्मीद वैसे ही जैसे निम्न अपवादों मैं:

गेटर विधि के लिए

पैरामीटर का प्रकार 'MyConcreteClass' का उपयोग के लिए 'MyAbstractClass <MyConcreteType>' के प्रतिनिधि पैरामीटर के लिए नहीं किया जा सकता है।

क्या इस तरह के कास्टिंग को "मजबूर" करने का कोई तरीका है? अग्रिम में धन्यवाद।

+1

यह प्रश्न बेहद भ्रमित है। "MyConcreteClass" नामक एक अमूर्त वर्ग क्यों है। "कंक्रीट" और "अमूर्त" विरोधी हैं; क्या यह जानबूझकर भ्रमित करने का इरादा है? क्या दो "टी" समान हैं, या दो अलग-अलग वर्गों में टी की दो अलग-अलग घोषणाएं हैं? आप इस अजीब चीज़ को पहली जगह क्यों करने की कोशिश कर रहे हैं? –

उत्तर

11

अगर मैं आपके सवाल का सही ढंग से समझ, तो आप इस तरह एक लैम्ब्डा अभिव्यक्ति बनाना चाहते हैं:

Func<MyAbstractClass<T>, Object> f = i => ((MyConcreteClass)i).SomeProperty; 

छोड़कर उपलब्ध कराने की जो संपत्ति SomeProperty एक पैरामीटर के रूप है चाहता हूँ। खैर, यदि आप उस अभिव्यक्ति को प्रोग्रामेटिक रूप से बनाना चाहते हैं, तो आपको बिल्कुल वही करना होगा: अभिव्यक्ति पैरामीटर i (MyAbstractClass<T> टाइप करें), इसे MyConcreteClass पर डालें और फिर उसमें SomeProperty संपत्ति का उपयोग करें।

public Func<MyAbstractClass<T>, Object> GetPropertyGetter(PropertyInfo property) 
{ 
    var parameter = Expression.Parameter(typeof(MyAbstractClass<T>), "i"); 

    var cast = Expression.TypeAs(parameter, property.DeclaringType); 

    var getterBody = Expression.Property(cast, property); 

    var exp = Expression.Lambda<Func<MyAbstractClass<T>, Object>>(
     getterBody, parameter); 

    return exp.Compile(); 
} 

करने के बाद कहा कि, मैं बिल्कुल पता नहीं क्यों आप ऐसा करना चाहते हैं होता है, ताकि आप बेहतर वास्तव में यकीन है कि यह है कि आप क्या करना चाहते हैं हो सकता है और वहाँ तुम क्या कर के किसी भी बेहतर तरीका नहीं है कि वास्तव में करना चाहते हैं।

+0

+1 मैं 'Expression.TypeAs' का नमूना ढूंढ रहा था। साझा करने के लिए धन्यवाद। – digaomatias

0

क्या आप जेनेरिक प्रकार से इंस्टेंस प्रकार नहीं बना रहे हैं?

var genericType = typeof(MyAbstractClass<>).MakeGenericType(property.DeclaringType); 
var instanceType = Expression.Parameter(genericType , "i"); 
संबंधित मुद्दे