在C#中,如何创建将委托类型映射到委托类型的委托类型?
特别是,在我下面的示例中,我想声明一个委托Sum
,使其(借用数学符号)Sum(f,g) = f + g
。然后我想调用Sum(f,g)
- 例如Sum(f,g)(5)
[这意味着f(5) + g(5)
]。
class Example
{
delegate int IntToInt ( int i ) ;
public static int Double ( int i ) { return i * 2 ; }
public static int Square ( int i ) { return i * i ; }
delegate IntToInt IntToIntPair_To_IntToInt ( IntToInt f, IntToInt g ) ;
public static IntToInt Sum ( IntToInt f, IntToInt, g ) { return f + g ; }
public static void Main ( )
{
IntToInt DoubleInstance = Double ;
IntToInt SquareInstance = Square ;
IntToIntPair_To_IntToInt SumInstance = Sum ;
System.Console.WriteLine
( SumInstance ( DoubleInstance, SquareInstance ) ( 5 ) ) ;
// should print 35 = 10 + 25 = Double(5) + Square(5)
}
}
答案 0 :(得分:14)
您只需要表达具体类型即可。例如:
Func<Func<int, int>, Func<int, int>>
表示一个函数,它接受(将int转换为第二个int的函数)并返回(将int转换为第二个int的函数)。或者采取两个函数并返回第三个函数:
Func<Func<int, int>, Func<int, int>, Func<int, int>>
例如:
Func<Func<int, int>, Func<int, int>> applyTwice = (f => x => f(f(x));
这可以通过以下方法返回:
public static Func<Func<T,T>, Func<T,T>> ApplyTwice<T>()
{
return func => x => func(func(x));
}
如果要总结两个函数,可以这样做:
public static Func<int, int> Sum(Func<int, int> first, Func<int, int> second)
{
return x => first(x) + second(x);
}
现在申请:
Func<int, int> doubler = x => x * 2;
Func<int, int> squarer = x => x * x;
Func<int, int> doublePlusSquare = Sum(doubler, squarer);
Console.WriteLine(doublePlusSquare(5)); // Prints 35
(未经测试,但应该没问题......)
如果您没有可用的C#3和.NET 3.5,请声明以下代理:
public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T arg);
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
(我的C# Versions page还有更多内容。)
然后你需要使用匿名方法,例如
public static Func<int, int> Sum(Func<int, int> first, Func<int, int> second)
{
return delegate(int x) { return first(x) + second(x); };
}
Func<int, int> doubler = delegate (int x) { return x * 2; };
Func<int, int> squarer = delegate (int x) { return x * x; };
Func<int, int> doublePlusSquare = Sum(doubler, squarer);
Console.WriteLine(doublePlusSquare(5)); // Prints 35
答案 1 :(得分:0)
Func<int, int> f = i => i * 2;
Func<int, int> g = i => i * i;
Func<int, int> sum = i => f(i) + g(i);
但是,如果你想为Func&lt; int,int&gt;之外的其他类型创建一个Sum方法,你必须使用
static Func<T, T> Sum<T>(Func<T, T> f, Func<T, T> g)
{
ParameterExpression p = Expression.Parameter(typeof(T), "i");
Expression<Func<T, T>> sumExpression =
Expression.Lambda<Func<T, T>>(
Expression.Add(
Expression.Invoke(Expression.Constant(f), p),
Expression.Invoke(Expression.Constant(g), p)),
p);
return sumExpression.Compile();
}
这适用于定义“+”运算符的任何类型T. 请注意编译lambda表达式所带来的性能损失。