2009-04-08 14 views
50

मैं खोज किया गया है, लेकिन मैं कैसे प्रकारअभिव्यक्ति के लिए अभिव्यक्ति <समारोह <T, DateTime>> कास्ट करने के लिए कैसे <समारोह <T, object>>

Expression<Func<T, DateTime>> 

से टाइप करने के लिए कास्ट करने के लिए नहीं मिल सकता है:

Expression<Func<T, object>> 

तो मुझे फिर से एसओ विशाल ज्ञान में बदलना चाहिए;)

उत्तर

62

आप केवल उनके बीच नहीं डाले जा सकते हैं, क्योंकि वे एक ही तरह की चीज़ नहीं हैं। हालांकि, अगर आप को प्रभावी ढंग से अभिव्यक्ति पेड़ के भीतर रूपांतरण जोड़ सकते हैं:

using System; 
using System.Linq.Expressions; 

class Test 
{ 
    // This is the method you want, I think 
    static Expression<Func<TInput,object>> AddBox<TInput, TOutput> 
     (Expression<Func<TInput, TOutput>> expression) 
    { 
     // Add the boxing operation, but get a weakly typed expression 
     Expression converted = Expression.Convert 
      (expression.Body, typeof(object)); 
     // Use Expression.Lambda to get back to strong typing 
     return Expression.Lambda<Func<TInput,object>> 
      (converted, expression.Parameters); 
    } 

    // Just a simple demo 
    static void Main() 
    { 
     Expression<Func<string, DateTime>> x = text => DateTime.Now; 
     var y = AddBox(x);   
     object dt = y.Compile()("hi"); 
     Console.WriteLine(dt); 
    }   
} 
+0

@JonSkeet Expression.Convert हमेशा एक अच्छा विचार नहीं है। मेरा जवाब देखें – Rookian

8

जॉन से कोड (धन्यवाद Btw) के आधार पर आप पूर्ण लचीलापन के लिए एक कदम आगे ले जा सकते हैं:

public static Expression<Func<TModel, TToProperty>> Cast<TModel, TFromProperty, TToProperty>(Expression<Func<TModel, TFromProperty>> expression) 
{ 
    Expression converted = Expression.Convert(expression.Body, typeof(TToProperty)); 

    return Expression.Lambda<Func<TModel, TToProperty>>(converted, expression.Parameters); 
} 
+0

क्या इसका कोई उपयोग उदाहरण है? –

23

जवाब से रोब और जॉन स्कीट एक समस्या है।

आप x => Convert(x.PropertyName) की तरह कुछ मिलता है, लेकिन अक्सर ASP.NET MVC के लिए उदाहरण के लिए यदि आप चाहते हैं इस x => x.PropertyName

की तरह एक अभिव्यक्ति तो Expression.Convert"प्रदूषण" कुछ मामलों के लिए अभिव्यक्ति है।

समाधान:

public static class LambdaExpressionExtensions 
{ 
    public static Expression<Func<TInput, object>> ToUntypedPropertyExpression<TInput, TOutput> (this Expression<Func<TInput, TOutput>> expression) 
    { 
     var memberName = ((MemberExpression)expression.Body).Member.Name; 

     var param = Expression.Parameter(typeof(TInput)); 
     var field = Expression.Property(param, memberName); 
     return Expression.Lambda<Func<TInput, object>>(field, param); 
    } 
} 

उपयोग:

Expression<Func<T, DateTime>> expression = ...; 
Expression<Func<T, object>> expr = expression.ToUntypedPropertyExpression(); 
+7

यह काम नहीं करता प्रतीत होता है। उदाहरण के लिए, मैं 'Int32' को 'ऑब्जेक्ट' में परिवर्तित करने में सक्षम नहीं प्रतीत होता; 'कन्वर्ट' कॉल यही है। इसके बिना मुझे 'ArgumentException' मिलता है। 'डेटटाइम' संस्करण की कोशिश कर रहा है, वही बात। यदि यह आपके लिए काम करता है, तो मुझे लगता है कि आपने इसे संदर्भ प्रकार के साथ किया है। –

0

बस, वस्तु के रूप में बाहर TResult को परिभाषित करने और अभिव्यक्ति संकलन यह सब डेटा प्रकार के लिए काम करता है;

Expression<Func<string, object>> dateExp = text => DateTime.Now; 
object dt = dateExp.Compile()("hi"); 
Console.WriteLine(dt); 

Fiddle sample here

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