什么是委托?

3

我经常使用代理(Actions、WaitCallbacks和Funcs),但我正在努力更好地了解它们的“本质”。

我对对象与引用类型等方面有相当好的理解,知道它们存储在堆栈上的位置?

基本上,我正在尝试从性能角度理解使用代理。是否有任何资源链接或良好的解释可以提供?

另外,事件究竟是什么?它们与代理有什么关系?它们基本上只是一个迭代的代理列表吗?


只是让你知道,堆栈与堆的区别是一种实现细节——而且是一种误导性过于简化的实现细节。堆可以存储堆栈可以存储的任何内容,否则你就不能在对象内部拥有一个“int”字段。 - cHao
ildasm 将回答你所有的问题。 - SK-logic
4个回答

2
到目前为止,所有说的都是正确的。下面是它在内部的工作原理:委托有两个字段:可执行代码的指针和表示this参数的对象类型的字段(您可以将委托添加到实例方法)。
当您调用此委托时,CPU将把该代码的指针提取到寄存器中,然后“调用”此指针。调用指令不需要使用常量值。CPU可以跳转到内存中的变量位置。
事件只是委托加上两个包装器方法,用于附加新委托或删除现有委托。令人困惑的部分是委托具有我略去的第三个字段:一个委托!委托形成链表。这称为MulticastDelegate,它是一种可怕的东西。当您调用委托时,它可能会导致调用具有相同签名的多个方法。这就是事件的工作方式。事件是委托类型的单个字段。
现在忘记MulticastDelegate,因为它们在实践中不相关。

当你说“CPU可以跳转到内存中的变量位置”时,你是在谈论堆栈还是堆?那么事件又如何融入其中呢? - William
我添加了一个关于事件的段落。我不明白你所说的“堆栈或堆”。这与委托有什么关系?CPU不会跳转到数据(在堆栈或堆上)。它会跳转到位于运行时内部代码堆上的Jitted代码。代码只是内存中的字节。 - usr
也许你误读了“变量位置”。这与变量无关。位置本身是可变的,无法静态确定。它是一个指针。 - usr

0

委托是表示函数的数据结构 - 包括返回类型和参数(类型和数量)。任何与委托返回类型和签名匹配的方法都可以分配给这样的委托。

就性能而言 - 这是一个额外的抽象层,但很小。这不是你可能会注意到的事情。


0

从我的理解来看,委托可以有两种类型:

  • "实例绑定方法指针",这意味着委托包含订阅对象的对象实例和要调用的对象类中的方法。如果我有MyClass.Handler(),并且我创建五个MyClass实例,并为每个实例创建5个委托,指向Handler()方法,则每个委托将具有相同的方法指针,但是不同的对象实例。

  • 静态方法指针,例如,委托到静态方法,在这种情况下,不需要对象上下文。

事件是MulticastDelegate对象,您甚至可以检查它们以查看谁订阅了事件。使用反射,您可以审计事件的订阅者。


0
委托是 C# 语言中的一个元素,它允许您引用一个方法。如果您是 C 或 C++ 程序员,这听起来很熟悉,因为委托基本上就是一个函数指针。然而,使用其他语言的开发人员可能会想知道,“为什么我需要一个方法的引用?”答案归结为在运行时给您提供实现任何功能的最大灵活性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接