0

我有(例如)一个Func<int, int>我想像往常一样调用的,除了参数的类型为objectrater than int。我只知道 Func 的确切类型和运行时的参数,因为 Func 是使用表达式树创建的,现在可以从dynamic变量中访问。(简化)代码示例:

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

如何使代码转换arg为整数或参数的任何类型?我尝试制作一个通用方法,将对象转换为某种类型,然后通过反射调用它,如下所示:

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

对于getFromFunc

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

MethodInfo.Invoke也有回报object。关于如何确保参数具有正确类型的任何想法?

4

3 回答 3

4

所有委托都派生自 System.Delegate。您可以使用 System.Delegate.DynamicInvoke 方法调用在编译时您不知道其类型的委托,类似于使用 MethodInfo.Invoke() 调用方法。例如:

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);
    }
}
于 2013-05-09T20:47:20.017 回答
3

你已经在使用了dynamic,为什么不使用dynamic呢?

return dynFunc((dynamic)arg);

这确保了arg的运行时类型被用于确定它是否是一个合适的参数。

于 2013-05-09T19:51:40.150 回答
0

这样的事情呢?

public static int Main(string[] args)
{
    // this could be any other lambda expression
    Func<object, object> unknownFunc = (a) => { return 13; };

    int result = (int) unknownFunc(13);
    Console.WriteLine(result);

    return 0;
}
于 2013-05-09T19:59:16.900 回答