当只在运行时知道Type时,如何使用表达式树来调用generics方法?

这是我用reflection解决的问题,但是想看看如何使用表达式树来完成它。

我有一个通用的function:

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

我需要在class上的其他地方打电话。 现在,通常情况下,这很简单:

 DoSomeThing( blah ); 

但只有我知道,在设计时我正在使用int 。 当我不知道类型,直到运行时我需要帮助。 就像我说的,我知道如何通过reflection来做到这一点,但我想通过表达式树来做,因为我(非常有限)的理解是我可以这样做。

我可以获得这种理解的网站的任何建议或指向,最好是样本代码?

MethodInfo.MakeGenericMethod

然后只需创建一个委托并调用它。 (当然不是表达; p)

更新:

通常,我更喜欢使用generics类型, Activator.CreateInstance只需要更少的工作。 一切都取决于你的情况。

是的,它可以通过表达式树来完成。 优点是您获得了一个委托,因此重复调用将比一遍又一遍地执行MethodInfo.Invoke()快得多。 dynamic关键字也可以这样做。

例:

 What type would you like to use? decimal Selected type 'System.Decimal' Input Value: 5.47 <<>> The object has static type 'System.Object', dynamic type 'System.Decimal', and value '5.47' <<>> The object has static type 'System.Decimal', dynamic type 'System.Decimal', and value '5.47' <<>> The object has static type 'System.Decimal', dynamic type 'System.Decimal', and value '5.47' <<>> 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) { 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("<<>>"); LogObject(o); Console.WriteLine("<<>>"); LogObject((dynamic)o); Console.WriteLine("<<>>"); Action f = LogObject; MethodInfo logger = f.Method.GetGenericMethodDefinition().MakeGenericMethod(userType); logger.Invoke(null, new[] { o }); Console.WriteLine("<<>>"); var p = new[] { Expression.Parameter(typeof(object)) }; Expression> e = Expression.Lambda>( Expression.Call(null, logger, Expression.Convert(p[0], userType) ) , p); Action a = e.Compile(); a(o); } } }