是否有内置的方法在各种类型的Func代理之间进行转换?也就是说,假设您需要一个Func,但是您有一个Func(并且您具有应该为T参数传递的值)。例如:
static TREsult Foo<TResult>(Func<TResult> f)
{
// ...
TResult result = f();
// ...
return result;
}
static int MyFunc(int i)
{
return i;
}
void CallFoo()
{
Func<int> func = ConvertFunc(MyFunc, 1); // Does this family of methods exist?
int j = Foo(func);
}
我写了自己的,像这样:
static Func<TResult> ConvertFunc<T, TResult>(Func<T, TResult> f1, T t)
{
return () => f1(t);
}
static Func<TResult> ConvertFunc<T1, T2, TResult>(Func<T1, T2, TResult> f2, T1 t1, T2 t2)
{
return () => f2(t1, t2);
}
// etc.
但我想知道是否存在这样的一系列方法(或者即使有更好的方法可以做到这一点)。
基本上,我是这样做的,在一个方法中有一些锅炉板代码,后跟一个函数调用(函数中的数字和类型会有所不同,但返回类型是相同的),其次是通过更多锅炉板代码。
欢迎所有意见!感谢。
答案 0 :(得分:3)
static Func<TResult> ConvertFunc<T, TResult>(Func<T, TResult> f1, T t)
{
return () => f1(t);
}
对我来说,这种代码看起来有点危险 - 不是说本身有什么不对,但需要小心。您正在使用闭包在函数中嵌入输入变量。但是这可能会导致很多错误,因为如果变量在转换Func
和运行它之间发生变化,结果会有所不同。
我只是好奇什么是好处。您是否试图隐藏功能消费者的输入参数?只要该变量是传递给它的本地变量,就可以了。
就解决方案而言,由于完全出于同样的原因,.NET已经创建了16个不同的通用Func<>
,因此不会有。
你也许可以使用反射来实现一个解决方案,但是你会因为调用函数而受到惩罚。 MethodInfo.GetGenericArguments()
会为您提供类型,然后您可以使用MethodInfo.MakeGenericMethod()
创建新类型。
只是为了说明我的观点:
static int Double(int number)
{
return number * 2;
}
static void Main(string[] args)
{
int i = 2;
Func<int> f = () => Double(i);
i = 3;
Console.WriteLine(f()); // prints 6 and not 4
}