我编写了一个尝试动态执行以下操作的小函数:
Func<object, object> fa = i => Convert.ChangeType(i, typeof (string));
Func<int, string> fb = o => (string) fa((int)o);
函数如下:
/// <summary>
/// Converts <see cref="Func{object, object}" /> to <see cref="Func{T, TResult}" />.
/// </summary>
public static Delegate Convert(Func<object, object> func, Type argType, Type resultType)
{
Contract.Requires(func != null);
Contract.Requires(resultType != null);
var param = Expression.Parameter(argType);
var converted = Expression.Convert(
Expression.Call(func.Method, Expression.Convert(param, typeof (object))),
resultType);
var delegateType = typeof (Func<,>).MakeGenericType(argType, resultType);
return Expression.Lambda(delegateType, converted, param).Compile();
}
现在,当不涉及闭包时,这可以正常工作 - 此测试通过:
[Test]
public void When_Converting_Without_Closure_Then_Suceeds()
{
// Arrange
Func<object, object> f = i => Convert.ChangeType(i, typeof(string));
var sut = FuncConversion.Convert(f, typeof(int), typeof(string));
// Act
var res = (string) sut.DynamicInvoke(10);
// Assert
Assert.AreEqual(typeof(Func<int, string>), sut.GetType());
Assert.AreEqual("10", res);
}
但是当涉及到闭包时,这个测试会失败:
[Test]
public void When_Converting_With_Closure_Then_Succeeds()
{
// Arrange
var typeTo = typeof (string);
Func<object, object> f = i => Convert.ChangeType(i, typeTo);
var sut = FuncConversion.Convert(f, typeof(int), typeof(string));
// Act
var res = (string)sut.DynamicInvoke(10);
// Assert
Assert.AreEqual(typeof(Func<int, string>), sut.GetType());
Assert.AreEqual("10", res);
}
System.ArgumentException :静态方法需要空实例,非静态方法需要非空实例。参数名称:System.Linq.Expressions.Expression.Call(MethodInfo method, Expression arg0) 中 System.Linq.Expressions.Expression.ValidateStaticOrInstanceMethod(Expression instance, MethodInfo method) 的方法
知道有什么问题吗?