我(例如)我想照常调用Func<int, int>
,但参数的类型为object
,而不是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
。
关于如何确保参数具有正确类型的任何想法?
答案 0 :(得分:3)
所有代表派生自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);
}
}
答案 1 :(得分:2)
您已使用dynamic
,为什么不使用dynamic
?
return dynFunc((dynamic)arg);
这可以确保arg
的运行时类型用于确定它是否是一个合适的参数。
答案 2 :(得分: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;
}