Comment utiliser un arbre d’expression pour appeler une méthode générique lorsque le Type est uniquement connu à l’exécution?

C’est quelque chose que j’ai résolu en utilisant la reflection, mais j’aimerais voir comment le faire en utilisant des arbres d’expression.

J’ai une fonction générique:

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

que j’ai besoin d’appeler ailleurs où dans ma classe. Maintenant, normalement, ce serait simple:

 DoSomeThing( blah ); 

mais seulement si je sais, au moment de la conception que je travaille avec un int . Quand je ne connais pas le type jusqu’à ce que l’exécution soit où j’ai besoin de l’aide. Comme je l’ai dit, je sais le faire via la reflection, mais j’aimerais le faire via des arbres d’expression, car ma compréhension (très limitée) est que je peux le faire.

Des suggestions ou des points vers des sites où je peux obtenir cette compréhension, de préférence avec un exemple de code?

MethodInfo.MakeGenericMethod

Ensuite, créez simplement un délégué et appelez-le. (pas dans une expression, bien sûr; p)

Mettre à jour:

Généralement, je préfère utiliser des types génériques pour cela, Activator.CreateInstance nécessite simplement moins de travail. Tout dépend de votre situation cependant.

Oui, cela peut être fait via des arbres d’expression. L’avantage est que vous obtenez un délégué, les appels répétés seront donc beaucoup plus rapides que de MethodInfo.Invoke() encore et encore MethodInfo.Invoke() . Le mot clé dynamic peut également le faire.

Exemple:

 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' 

Code:

 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.ToSsortingng() + "'"); } static void Main(ssortingng[] args) { Console.WriteLine("What type would you like to use?"); ssortingng 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 "ssortingng": userType = typeof(ssortingng); break; case "decimal": userType = typeof(decimal); break; default: userType = Type.GetType(typeName); break; } Console.WriteLine("Selected type '" + userType.ToSsortingng() + "'"); Console.WriteLine("Input Value:"); ssortingng 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.Comstack(); a(o); } } }