(如何)是否可以绑定/重新绑定一个方法以与不同签名的委托一起使用?
我是一名 C++ 开发人员,曾使用过信号和信号。 C++ 中的插槽对我来说似乎类似于 C# 中的委托。我发现自己在寻找“bind”提供的功能时不知所措,感觉我一定错过了一些东西。
我觉得像下面这样的东西,在 c++ 中是可能的,在带有委托的 c# 中也应该是可能的。以下是我在 c++ 中执行的操作的一些伪代码:
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# 中是否有一些完全不同的方法来做到这一点?
I'm a c++ developer having used signals & slots in c++ which to me seems to be analogous to delegates in c#. I've found myself at a loss in searching for the functionality provided by "bind", and feel I must be missing something.
I feel like that something like the following, which is possible in c++ should be possible in c# with delegates. Here is some psudo-code for what I would do in c++:
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;
}
Unfortunately, I've not been able to find any reference to binding/rebinding with regards to c# delegates. Am I missing something? Is there some radically different way to do this in c#?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在 C# 中,我们这样做:
显然,方法
Foo
对应于您的方法Foo
,只需适当调用Console.WriteLine
而不是std::cout
。接下来,我们声明一个方法
Curry
,它接受Action
并返回Action
。一般来说,Action
是接受T
类型的单个参数并返回void
的委托。特别是,Foo
是一个Action
,因为它接受一个int
类型的参数并返回void
。至于Curry
的返回类型,它被声明为Action
。Action
是一个委托,没有参数并返回void
。Curry
的定义相当有趣。我们使用 lambda 表达式定义一个操作,这是一种非常特殊的匿名委托形式。实际上表示
void
参数映射到在parameter
处计算的action
。最后,在
Main
中,我们声明一个名为curried
的Action
实例,它是将Curry
应用到 < code>Foo 与参数5
。这与 C++ 示例中的bind(fun_ptr(foo), 5)
的作用相同。最后,我们通过语法
curried()
调用新形成的委托curried
。这就像您的示例中的someCallback()
。对此的奇特术语是柯里化。
作为一个更有趣的示例,请考虑以下内容:
这里我们声明了一个接受委托的方法
Curry
(Func
接受两个参数)相同类型TArg
并返回某种其他类型TResult
的值和类型TArg
的参数,并返回接受单个类型参数的委托TArg
并返回一个TResult
类型的值(Func
)。然后,作为测试,我们声明一个方法
。 Add
接受两个int
类型的参数并返回一个int
类型的参数(aFunc
然后在Main
中,我们实例化一个名为addFive
的新委托,它的作用类似于将 5 添加到其输入参数中的方法,从而打印
12
。控制台。In C# we do something like this:
Clearly the method
Foo
corresponds to your methodFoo
, just with the appropriate calls toConsole.WriteLine
instead ofstd::cout
.Next, we declare a method
Curry
that accepts anAction<T>
and returns anAction
. In general, anAction<T>
is a delegate that accepts a single parameter of typeT
and returnsvoid
. In particular,Foo
is anAction<int>
because it accepts one parameter of typeint
and returnsvoid
. As for the return type ofCurry
, it is declared as anAction
. AnAction
is a delegate the has no parameters and returnsvoid
.The definition of
Curry
is rather interesting. We are defining an action using a lambda expression which is a very special form of an anonymous delegate. Effectivelysays that the
void
parameter is mapped toaction
evaluated atparameter
.Finally, in
Main
we are declaring an instance ofAction
namedcurried
that is the result of applyingCurry
toFoo
with the parameter5
. This plays the same role asbind(fun_ptr(foo), 5)
in your C++ example.Lastly, we invoke the newly formed delegate
curried
via the syntaxcurried()
. This is likesomeCallback()
in your example.The fancy term for this is currying.
As a more interesting example, consider the following:
Here we are declaring a method
Curry
that accepts a delegate (Func<TArg, TArg, TResult>
that accepts two parameters of the same typeTArg
and returns a value of some other typeTResult
and a parameter of typeTArg
and returns a delegate that accepts a single parameter of typeTArg
and returns a value of typeTResult
(Func<TArg, TResult>
).Then, as a test we declare a method
Add
that accepts two parameters of typeint
and returns a parameter of typeint
(aFunc<int, int, int>
). Then inMain
we instantiate a new delegate namedaddFive
that acts like a method that adds five to its input parameter. Thusprints
12
on the console.尝试以下
或者更接近 C++ 对应部分的
解释。这里发生的是我通过 lambda 表达式创建一个新的委托。 lambda 是以
() =>
开头的表达式。在这种情况下,它创建一个不接受任何参数且不产生任何值的委托。它与Action
类型兼容。Try the following
Or for something even closer to the C++ counter part
Explanation. What's happening here is that I am creating a new delegate by means of a lambda expression. The lambda is the expression starting with
() =>
. In this case it creates a delegate accepting no arguments and producing no value. It is compatible with the typeAction
.