(如何)绑定/重新绑定方法以使用不同签名的委托?
我是一个c ++开发人员,在c ++中使用了信号和插槽,这对我来说似乎与c#中的委托类似。 我发现自己在寻找“绑定”提供的function时感到很茫然,并且觉得我必须遗漏一些东西。
我觉得像C ++这样的东西应该可以在c#中使用委托。 这里有一些psudo代码,用于我将在c ++中做什么:
Slot someCallback; int foo(int i) { std::cout << "Value: " << i << "\n"; return i; } int main() { int i = 0; Slot 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#delegates的绑定/重新绑定的引用。 我错过了什么吗? 在c#中有一些根本不同的方法吗?
在C#中我们做这样的事情:
class Program { static Action Curry(Action 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
。
接下来,我们声明一个接受Action
并返回Action
的方法Curry
。 通常, Action
是一个委托,它接受类型为T
的单个参数并返回void
。 特别是, Foo
是一个Action
因为它接受一个int
类型的参数并返回void
。 至于Curry
的返回类型,它被声明为Action
。 Action
是一个委托,它没有参数并返回void
。
Curry
的定义相当有趣。 我们使用lambda表达式定义一个动作,这是一种非常特殊的匿名委托forms。 有效
() => action(parameter)
表示void
参数映射到在parameter
计算的action
。
最后,在Main
我们声明了一个名为curried
的Action
实例,它是使用参数5
将Curry
应用于Foo
的结果。 这bind(fun_ptr(foo), 5)
您的C ++示例中的bind(fun_ptr(foo), 5)
扮演相同的角色。
最后,我们通过语法curried()
调用新形成的委托。 这就像你的例子中的someCallback()
。
这个花哨的术语是讨好的 。
作为一个更有趣的例子,请考虑以下事项:
class Program { static Func Curry( Func func, TArg arg1 ) { return arg => func(arg1, arg); } static int Add(int x, int y) { return x + y; } static void Main(string[] args) { Func addFive = Curry(Add, 5); Console.WriteLine(addFive(7)); } }
这里我们声明一个接受委托的方法Curry
( Func
接受相同类型TArg
两个参数并返回其他类型的值TResult
和TArg
类型的参数并返回一个接受的委托TArg
类型的单个参数,返回TResult
类型的值( Func
)。
然后,作为测试,我们声明一个方法Add
,它接受两个int
类型的参数,并返回一个int
类型的参数(一个Func
)。 然后在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(Action action, T value) { return () => action(value); } public static void Main() { Action someCallback = bind(foo, 5); someCallback(); } }
说明。 这里发生的是我正在通过lambda表达式创建一个新的委托。 lambda是以() =>
开头的表达式。 在这种情况下,它创建一个委托,不接受任何参数并且不产生任何值。 它与Action
类型兼容。