(如何)是有可能绑定/重新绑定到工作方法具有不同的签名的委托?
-
21-09-2019 - |
题
我具有在C ++中使用的信号及时隙的C ++开发这对我似乎类似于在C#代表。我发现自己处于亏损中搜索由“绑定”提供的功能,觉得我一定是失去了一些东西。
我感觉类似的东西等的下面,这是可能的在C ++中应在C#与代表是可能的。这里是什么,我将会用C ++做一些psudo代码:
Slot<void> someCallback;
int foo(int i)
{
std::cout << "Value: " << i << "\n";
return i;
}
int main()
{
int i = 0;
Slot<int> someCallback = bind( fun_ptr(foo), i );
++i; // added to show that late evaluation would be a non-trivial difference
int result = someCallback();
assert( result == 0 );
return 0;
}
不幸的是,我一直没能找到结合/关于C#代表重新绑定任何引用。我缺少的东西吗?有一些完全不同的方式在C#这样做吗?
解决方案
在C#中,我们做这样的事:
class Program {
static Action Curry<T>(Action<T> action, T parameter) {
return () => action(parameter);
}
static void Foo(int i) {
Console.WriteLine("Value: {0}", i);
}
static void Main(string[] args) {
Action curried = Curry(Foo, 5);
curried();
}
}
显然该方法Foo
对应于你的方法Foo
,只是用适当的调用Console.WriteLine
代替std::cout
。
接下来,我们声明,接受一个Curry
并返回一个Action<T>
的方法Action
。通常,Action<T>
是接受型T
并返回void
的单个参数的委托。特别地,Foo
是Action<int>
因为它接受型int
并返回void
的一个参数。至于Curry
的返回类型,它被声明为Action
。一个Action
为代表的不具有任何参数和返回void
。
Curry
的定义是相当有趣。我们定义使用lambda表达式是匿名委托的一个非常特殊形式的行动。有效地
() => action(parameter)
说,void
参数映射到action
在parameter
评价。
最后,在Main
我们宣布命名Action
curried
的实例,它是与参数Curry
施加Foo
到5
的结果。这起着相同的作用,因为bind(fun_ptr(foo), 5)
在C ++例子。
最后,我们通过调用的语法curried
新形成的委托curried()
。这就好比在你的例子someCallback()
。
这种情况的花式术语是钻营。
作为一个更有趣的例子,考虑以下:
class Program {
static Func<TArg, TResult> Curry<TArg, TResult>(
Func<TArg, TArg, TResult> func,
TArg arg1
) {
return arg => func(arg1, arg);
}
static int Add(int x, int y) {
return x + y;
}
static void Main(string[] args) {
Func<int, int> addFive = Curry<int, int>(Add, 5);
Console.WriteLine(addFive(7));
}
}
下面我们宣布接受委托(Curry
接受相同类型Func<TArg, TArg, TResult>
的两个参数,并返回一些其他类型的TArg
的值和类型TResult
的参数,并返回一个接受的单个参数的委托的方法TArg
型TArg
并返回型TResult
(Func<TArg, TResult>
)的值。
然后,作为测试我们声明,接受类型Add
的两个参数,并返回型int
(一个int
)的参数的方法Func<int, int, int>
。然后在Main
我们实例化一个新的委托命名addFive
行为像,增加了五到它的输入参数的方法。因此
Console.WriteLine(addFive(7));
打印12
在控制台上。
其他提示
尝试以下方法
class Example {
static void foo(int i) {
Console.WriteLine(i);
}
public static void Main() {
Action someCallback = () => foo(5);
someCallback();
}
}
或者对于一些更接近C ++计数器部分
class Example {
static void foo(int i) {
Console.WriteLine(i);
}
static Action bind<T>(Action<T> action, T value) {
return () => action(value);
}
public static void Main() {
Action someCallback = bind(foo, 5);
someCallback();
}
}
解释。这里发生的事情是,我通过一个lambda表达式来创建一个新的委托。拉姆达是开始() =>
表达。在这种情况下,它创建一个委托接受没有参数和产生任何值。它与类型Action
兼容。