나는 동적으로 다음을 수행하려고 시도 약간의 기능을 작성했습니다 :<T, TRet>
는 Func<object, object> fa = i => Convert.ChangeType(i, typeof (string));
Func<int, string> fb = o => (string) fa((int)o);
FUNC은 다음과 같다 :
/// <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);
}
하지만 때 교류 losure이 테스트가 실패 관여 :
[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 정적 메소드는 null 인스턴스는 비 정적 메소드가 null 인스턴스를 필요로 요구한다. 매개 변수 이름 : System.Linq.Expressions.Expression.Call에서 System.Linq.Expressions.Expression.ValidateStaticOrInstanceMethod (표현의 예를, MethodInfo 방법) 의 방법 (MethodInfo 방법, 표현적인 것들은 arg0)
어떤 생각 어떤 문제가 있는지 ?
좋아, 나는 거기 FUNC에 대한 숨겨진 폐쇄 PARAM이고 나는 그것의 존재를 모르고, 무슨 무슨 내가 아는 생각합니다. Expression.Invoke를 사용해 보겠습니다. – DanH
이런 식으로 수행보다는 매우 간단한 방법으로 어떤 이유'개인 정적 Func을 변환 (Func을
예, 일반 매개 변수로 T1/T2가 없습니다. 동적으로 그 메소드를 호출 할 수 있습니다. 비록 오버 헤드가있을 때마다 호출됩니다. – DanH