对于一些奇特的反射材料,我有一个类型为Func的函数,需要将它传递给一个接受类型Func的函数,其中T在运行时间之前是未知的。例如:创建一种函数将一种类型的函数转换为另一种类型
public bool MyOperation(Func<string,bool> op) {
return _myValues.Any(op);
}
public static bool InvokeOperationMethod(MethodInfo info, object obj,Func<object,bool> opAsObject)
{
info.Invoke(obj, opAsObject);
}
的问题是,因为我有一个弱类型的拉姆达,我不能把它作为一个更强的类型的参数。所以我试图建立一个帮助器,它将创建一个将弱类型的lambda转换为更强类型的函数。例如,我可以打电话给
var converter = CreateConverter(typeof(string));
Func<object,bool> asObject = o => o.ToString() == "a string"; //Dump example
Func<string,bool> asString = (Func<string,bool>)converter(asObject);
Assert.IsTrue(asInt("a string"));
当然在实际的代码此目标类型不知道,直到运行时间,以及实际的谓词不是一些琐碎的考验。
这是我的尝试:
/// <summary>
/// Converts a predicate of Func<object,bool> to
/// Func<Type,bool> of the given type.
/// </summary>
/// <param name="destType">Type of the dest.</param>
/// <param name="predicate">The predicate.</param>
/// <returns></returns>
public static TransformPredicate CreateConverter(Type destType)
{
// This essentially creates the following lambda, but uses destType instead of T
// private static Func<Func<object, bool>, Func<T, bool>> Transform<T>()
// {
// return (Func<object,bool> input) => ((T x) => input(x));
// }
var input = Expression.Parameter(typeof(Func<object, bool>), "input");
var x = Expression.Parameter(destType, "x");
var convert = Expression.Convert(x, typeof(object));
var callInputOnX = Expression.Invoke(input, convert);
var body2 = Expression.Lambda(callInputOnX, x);
var body1 = Expression.Lambda(typeof(TransformPredicate),body2, input);
return (TransformPredicate) body1.Compile();
}
public delegate object TransformPredicate(Func<object,bool> weak);
其实,这只是正常工作,但它运行非常缓慢,因为它隐含在每次调用调用createDelegate方法。所以,我想通过增加调用createDelegate方法自己:
var destFunc = typeof(Func<,>).MakeGenericType(destType, typeof(bool));
var endType = typeof(Func<,>).MakeGenericType(typeof(Func<object, bool>), destFunc);
return (TransformPredicate)compiled.Method.CreateDelegate(endType);
这将导致一个错误:
System.NotSupportedException: Derived classes must provide and implementation.
任何想法如何,我可以叫我createDelegate方法?
这可能有助于http://msdn.microsoft.com/en-us/library/bb292051.aspx –
我不明白。为什么你不能只调用asObject(“字符串”)?我认为重要的是你将如何使用这个结果,所以如果你表明这一点会有所帮助。 – svick