2010-03-12 4 views
12

यह ऐसा कुछ है जिसे मैंने प्रतिबिंब का उपयोग करके हल किया है, लेकिन यह देखना चाहते हैं कि अभिव्यक्ति पेड़ों का उपयोग करके इसे कैसे किया जाए।टाइप जेनरेट पर केवल ज्ञात होने पर सामान्य विधि को कॉल करने के लिए मैं अभिव्यक्ति वृक्ष का उपयोग कैसे कर सकता हूं?

private void DoSomeThing<T>(param object[] args) { 
    // Some work is done here. 
} 

है कि मैं अपने वर्ग में सब कहाँ से कॉल करने की आवश्यकता:

मैं एक सामान्य कार्य है। लेकिन

DoSomeThing<int>(blah); 

केवल तभी मुझे पता है, कि मैं एक int साथ काम कर रहा हूँ डिजाइन समय में: अब, सामान्य रूप से, इस सरल किया जा किया जाएगा। जब मैं रनटाइम तक टाइप नहीं जानता, जहां मुझे मदद की ज़रूरत है। जैसे मैंने कहा, मुझे पता है कि प्रतिबिंब के माध्यम से इसे कैसे करना है, लेकिन मैं इसे अभिव्यक्ति पेड़ों के माध्यम से करना चाहता हूं, क्योंकि मेरी (बहुत सीमित) समझ यह है कि मैं ऐसा कर सकता हूं।

साइट्स के लिए कोई सुझाव या अंक जहां मुझे यह समझ मिल सकती है, अधिमानतः नमूना कोड के साथ?

उत्तर

6

MethodInfo.MakeGenericMethod

तो बस एक प्रतिनिधि बना सकते हैं और यह कहते हैं। (नहीं पाठ्यक्रम की अभिव्यक्ति, में, पी)

अद्यतन:

आम तौर पर, मैं इस के लिए सामान्य प्रकार का उपयोग करना पसंद, Activator.CreateInstance बस कम काम की आवश्यकता है। हालांकि आपकी स्थिति पर निर्भर करता है।

+1

जैसा कि मैंने कहा, मुझे पता है कि प्रतिबिंब के माध्यम से यह करने के लिए। मैं अभिव्यक्ति पेड़ के माध्यम से करने का प्रयास कर रहा हूँ। –

+1

बस वही है, है ना? क्या मैं कुछ भूल रहा हूँ? (अद्यतन उत्तर) – leppie

5

हां, यह अभिव्यक्ति पेड़ के माध्यम से किया जा सकता है। लाभ यह है कि आप एक प्रतिनिधि प्राप्त करते हैं ताकि बार-बार कॉल MethodInfo.Invoke() बार-बार करने से कहीं अधिक तेज हो जाएंगी। dynamic कीवर्ड यह भी कर सकता है।

उदाहरण:

What type would you like to use? 
decimal 
Selected type 'System.Decimal' 
Input Value: 
5.47 
<<<USING object>>> 
The object has static type 'System.Object', dynamic type 'System.Decimal', and value '5.47' 
<<<USING dynamic>>> 
The object has static type 'System.Decimal', dynamic type 'System.Decimal', and value '5.47' 
<<<USING reflection>>> 
The object has static type 'System.Decimal', dynamic type 'System.Decimal', and value '5.47' 
<<<USING expression tree>>> 
The object has static type 'System.Decimal', dynamic type 'System.Decimal', and value '5.47' 

कोड:

using System; 
using System.ComponentModel; 
using System.Linq; 
using System.Linq.Expressions; 
using System.Reflection; 

namespace SO2433436 
{ 
    class Program 
    { 
     static void LogObject<T>(T t) 
     { 
      Console.WriteLine("The object has static type '" + typeof(T).FullName + "', dynamic type '" + t.GetType() + "', and value '" + t.ToString() + "'"); 
     } 

     static void Main(string[] args) 
     { 
      Console.WriteLine("What type would you like to use?"); 
      string typeName = Console.ReadLine(); 

      Type userType; 
      switch (typeName) 
      { 
       case "byte": userType = typeof(byte); break; 
       case "sbyte": userType = typeof(sbyte); break; 
       case "ushort": userType = typeof(ushort); break; 
       case "short": userType = typeof(short); break; 
       case "uint": userType = typeof(uint); break; 
       case "int": userType = typeof(int); break; 
       case "string": userType = typeof(string); break; 
       case "decimal": userType = typeof(decimal); break; 
       default: 
        userType = Type.GetType(typeName); 
        break; 
      } 

      Console.WriteLine("Selected type '" + userType.ToString() + "'"); 

      Console.WriteLine("Input Value:"); 
      string val = Console.ReadLine(); 

      object o = TypeDescriptor.GetConverter(userType).ConvertFrom(val); 

      Console.WriteLine("<<<USING object>>>"); 
      LogObject(o); 

      Console.WriteLine("<<<USING dynamic>>>"); 
      LogObject((dynamic)o); 

      Console.WriteLine("<<<USING reflection>>>"); 
      Action<object> f = LogObject<object>; 
      MethodInfo logger = f.Method.GetGenericMethodDefinition().MakeGenericMethod(userType); 
      logger.Invoke(null, new[] { o }); 

      Console.WriteLine("<<<USING expression tree>>>"); 
      var p = new[] { Expression.Parameter(typeof(object)) }; 
      Expression<Action<object>> e = 
       Expression.Lambda<Action<object>>(
        Expression.Call(null, 
            logger, 
            Expression.Convert(p[0], userType) 
            ) 
       , p); 
      Action<object> a = e.Compile(); 
      a(o); 
     } 
    } 
} 
संबंधित मुद्दे

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