C#中是否可以使用高阶函数,该函数使用具有任意数量和类型的参数以及返回值的函数,例如,
// No valid C# code
void MyFunction(Func f)
{
// do something
}
MyFunction(string.Join); // type: Func<String, IEnumerable<String>, String>
MyFunction(string.CompareTo); // type: Func<object, int>
// ...
我想,这个问题实际上归结为是否存在一个最通用的函数类型,它可以包含任何可能具有不同数量和类型的参数的函数。
我的用例如下:我有一个采用MethodInfo
对象的方法。目前,我做的事情就像
DoSomething(((Func<object, int>)string.CompareTo).Method)
然而,我必须为我期望的每种不同类型的功能重复这一点。我更喜欢DoSomething
本身可以确定类型的解决方案,所以我只给它函数本身而不是MethodInfo
对象。
编辑:
更确切地说,我正在使用ReLinq编写Linq-To-X提供程序。我从教程博客中获得了一些关于此主题的示例代码(https://www.codeproject.com/Articles/42059/re-linq-ishing-the-Pain-Using-re-linq-to-Implement和https://weblogs.asp.net/dixin/understanding-linq-to-sql-10-implementing-linq-to-sql-provider)。对于像Sum
或Count
这样的热切执行函数,我需要将它们包装到MethodCallExpression
对象中。
在示例代码中,它是这样解决的:
public static IQuery CountToSql<T>(this IQueryable<T> source)
{
ArgumentChecker.CheckNull(source, nameof(source));
var expression =
Expression.Call(
null,
GetMethodInfo(Queryable.Count, source),
new Expression[] { source.Expression }
);
return ToQuery(expression, ((DbQueryable<T>)source).SyntaxProvider);
}
private static MethodInfo GetMethodInfo<T1, T2>(Func<T1, T2> f, T1 unused1 => f.Method;
private static MethodInfo GetMethodInfo<T1, T2, T3>(Func<T1, T2, T3> f, T1 unused1, T2 unused2) => f.Method;
// ...
但是,我不想为每种类型的函数编写此函数(例如,Queryable.Sum
,Queryable.Count
,...)。目前的解决方案需要它。我只想要一个可以处理所有方法的方法,因为它们在90%时看起来相同。
答案 0 :(得分:0)
你需要从一个地方召集这样不同的代表,这似乎很奇怪。
我认为你需要像“EventDispatcher”这样的东西,当你的代码获得应该被转换为对象的数据时,但在调用之后你想要操作一个真实的对象。
如果我错了,请详细说明任务。
如果我是对的,你必须用泛型替换反射。创建方法,用Action包装委托。
public Action<object> WrapCall<T, K>( Func<T, K> func)
{
return (data) => func((T)data);
}
public Action<object, object> WrapCall<T1, T2, K>(Func<T1, T2,K> func)
{
return (t1Data, t2Data) => func((T1)t1Data, (T2)t2Data);
}
等等。
可能无法解决您的问题,但会帮助您以其他方式找到解决方案。