2012-01-25 261 views
3

我经常使用委托(Actions,WaitCallbacks,Funcs),但我试图更好地理解它们是什么。代表究竟是什么?

我对对象和引用类型等有相当好的理解,以及它们存储在堆对堆栈的位置?

基本上 - 我试图从性能的角度来理解代表。有没有人有任何资源链接或可能是一个很好的解释?

此外 - 什么是“事件”?他们如何与代表联系?他们基本上只是一个迭代的代表名单吗?

+0

可能重复的[有人可以提炼出适当的英文代表是什么?](http://stackoverflow.com/questions/2541683/can-someone-distill-into-proper-english-what-a-delegate-是) – Lucero

+0

就这么你知道,堆栈vs堆的东西是一个实现细节 - 并且是一个误导性过度简化的东西。堆可以存储堆栈可以存储的任何东西,否则你的对象内不能有'int'字段。 – cHao

+0

'ildasm'将回答你所有的问题 –

回答

2

到目前为止所说的一切都是正确的。下面是它是如何工作的:一个委托有两个字段:一个指向可执行代码的指针和一个表示这个参数的类型对象字段(你可以将委托委托给一个实例方法)。

当你调用这个委托时,CPU会将指向代码的指针提取到一个寄存器中,然后“调用”这个指针。调用指令不需要使用常量值。 CPU可以跳转到内存中的一个可变位置。

事件只是委托加两个包装方法来附加一个新的委托或删除一个现有的。令人困惑的部分是,代表们有第三个领域我离开了:代表!代表组成一个链表。这被称为MulticastDelegate,它是一种可憎的东西。当您调用委托时,它可能会导致多个具有相同签名的方法被调用。这是事件的工作方式。事件是委托类型的单个字段。

现在忘记了多播委托,因为它们在实践中并不相关。

+0

所以当你说'CPU可以跳到内存中的一个可变位置'时,你是在谈论堆栈还是堆?事件如何适应所有这些? – William

+0

我为事件添加了一段。我不明白“堆栈或堆”的含义。这与代表有什么关系? CPU不会跳转到数据(在堆栈或堆上)。它跳转到位于运行时内部代码堆上的Jitted代码。代码只是内存中的字节。 – usr

+0

也许你误读了“可变位置”。这与变量无关。该位置本身是可变的,它不能静态确定。它是一个指针。 – usr

0

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

在性能方面 - 这是一个额外的抽象层,但是很小。这不是你可能会注意到的。

0

代表可以有两种类型,从我的理解:

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

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

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

0

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