Rufen Sie Func <> mit dem Argument des Typs object auf

c# expression-trees func

Frage

Ich habe (zum Beispiel) einen Func<int, int> den ich wie üblich aufrufen möchte, außer dass der Parameter vom Typ object rater als int . Ich kenne nur den genauen Typ des Func und das Argument zur Laufzeit, weil der Func mit Hilfe von Ausdrucksbäumen erstellt wurde und jetzt von einer dynamic Variable aus zugegriffen wird. (Vereinfachter) Codebeispiel:

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
        }
    }
}

Wie kann ich den Code arg in eine Ganzzahl oder was auch immer Typ des Arguments konvertieren? Ich habe versucht, eine generische Methode zu erstellen, die das Objekt auf einen bestimmten Typ umwandelt und dann durch eine Reflektion wie folgt aufruft:

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

für getFromFunc :

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

Aber MethodInfo.Invoke auch ein object . Irgendwelche Ideen, um sicherzustellen, dass das Argument den richtigen Typ hat?

Akzeptierte Antwort

Sie verwenden bereits dynamic , warum also nicht dynamic ?

return dynFunc((dynamic)arg);

Dadurch wird sichergestellt, dass der Laufzeittyp von arg verwendet wird, um festzustellen, ob es sich um ein geeignetes Argument handelt.


Beliebte Antwort

Alle Delegaten stammen von System.Delegate. Sie können die System.Delegate.DynamicInvoke-Methode verwenden, um einen Delegat aufzurufen, dessen Typ Sie zur Kompilierzeit nicht kennen, ähnlich wie beim Aufrufen einer Methode mit MethodInfo.Invoke (). Beispielsweise:

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);
    }
}


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow