Appelez Func <> avec l'argument de type object

c# expression-trees func

Question

J'ai (par exemple) un Func<int, int> que je veux appeler comme d'habitude, sauf que le paramètre est de type object rater que int . Je ne connais que le type exact du Func et l'argument au moment de l'exécution, car le Func a été créé à l'aide d'arbres d'expression et est maintenant accessible à partir d'une variable dynamic . Exemple de code (simplifié):

using System.Linq.Expressions;

namespace FuncExample
{
    class Program
    {
        static void Main(string[] args)
        {
            object myFunc = CreateFunc(); // Could return something like
                                          // Func<int, int>, but may return a
                                          // completely different Func<> depending on
                                          // arguments etc.
            object result = getFromFunc(5, myFunc);
        }

        public static object CreateFunc()
        {
            LambdaExpression expr = Expression.Lambda(
                /*
                 * Create an expression
                 */
                );
            return expr.Compile();
        }

        public static object getFromFunc(object arg, object func)
        {
            dynamic dynFunc = func;
            return dynFunc(arg); // <------- Throws exception
        }
    }
}

Comment puis-je convertir le code en arg en un entier ou quel que soit le type d'argument? J'ai essayé de créer une méthode générique qui convertit l'objet vers un certain type, puis de l'invoquer par réflexion de la manière suivante:

public static T asT<T>(object n)
{
    return (T)n;
}

pour getFromFunc :

MethodInfo con = typeof(Program).GetMethod("asT").MakeGenericMethod(func.GetType().GetGenericArguments()[0]);
return dfunc(con.Invoke(null, new[] { value }));

Mais MethodInfo.Invoke renvoie également un object . Des idées sur la façon de s'assurer que l'argument a le type correct?

Réponse acceptée

Vous utilisez déjà dynamic , alors pourquoi ne pas utiliser dynamic ?

return dynFunc((dynamic)arg);

Cela garantit que le type d'exécution de arg est utilisé pour déterminer s'il s'agit d'un argument approprié.


Réponse populaire

Tous les délégués proviennent de System.Delegate. Vous pouvez utiliser la méthode System.Delegate.DynamicInvoke pour appeler un délégué dont vous ne connaissez pas le type au moment de la compilation, comme pour appeler une méthode à l'aide de MethodInfo.Invoke (). Par exemple:

class Program
{
    public static Delegate CreateFunc()
    {
      return new Func<int, int>(x => x + 1);
    }

    public static void Main(string[] args)
    {
        var func = CreateFunc();
        object inArg = 42;
        object result = func.DynamicInvoke(inArg);
        Console.WriteLine(result);
    }
}


Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow