C# 在类委托的哪个实例上被调用?
考虑一下这个代码C# 在类委托的哪个实例上被调用?,c#,events,delegates,C#,Events,Delegates,考虑一下这个代码 public class A { //... void f() { B b = new B(); b.SomeEvent += this.SomeMethod; } void SomeMethod() {} } public class B { //... public event SomeEventHandler SomeEvent; voi
public class A
{
//...
void f()
{
B b = new B();
b.SomeEvent += this.SomeMethod;
}
void SomeMethod() {}
}
public class B
{
//...
public event SomeEventHandler SomeEvent;
void h()
{
if ( SomeEvent != null )
{
SomeEvent.invoke();
}
}
}
在这个代码段中,SomeEvent.invoke()
实际上调用了类A
的SomeMethod()
。所以在这一点上,我有几个问题:
- 在
的哪个实例上调用A
?SomeMethod
如何知道要在哪个实例上调用委托?CLR在这里是如何工作的B
- 而且,
是一个私有方法,那么为什么SomeMethod
能够从类B
之外调用这个方法呢a
Delegate
有一个Target
属性,在该属性上可以调用Delegate。但我无法真正理解这个Target
属性设置的具体步骤是什么?谁定的?当我写b.SomeEvent+=this.SomeMethod时
,它是否也设置了目标
属性?具体如何?- 附加到事件时使用的任何实例
- 因为
在类外向其传递了一个委托表示A
特定的
委托
实例具有目标
属性;这表示调用委托时将使用的实例 委托包含调用方法的目标引用。您可以使用Delegate.Target
属性检查这一点。在这种情况下,将在调用f
的实例上调用它。(如果调用的是静态方法,则为null。)
至于隐私,这只是代表们的特点之一。您只能在有权访问私有方法的代码中创建委托,但可以在任何地方运行它。可以将其视为通过从公共接口实现中调用私有方法来实现接口
在SomeMethod的哪个实例上被调用?B如何知道要在其上调用委托的实例?CLR在这里是如何工作的
委托实际上包含对实际实例的引用。这将导致它在调用它的特定实例上调用
另外,SomeMethod是一个私有方法,那么为什么B能够从类a之外调用这个方法呢
它不直接执行方法,而是执行委托。这里有一个区别-私有约束只应用于方法,但是由于类本身创建委托,它可以访问方法,所以一切都正常
b.SomeEvent += this.SomeMethod
这里有很多糖,阻止你看到真正发生的事情。写出来后,它类似于:
b.SomeEvent.add(new MulticastDelegate(this, SomeMethod)); // not legal code
其中add()是事件的add访问器,当您不显式声明自己的访问器时,编译器会自动生成一个。委托构造函数的第一个参数是您询问的对象实例,即委托对象的目标属性。请注意,这会产生副作用,事件订阅会保留对b
对象的引用。这会阻止它被垃圾收集,这在调用事件时会非常糟糕
这也可能是一个问题,您可能会无意中泄漏对象引用。您的代码中没有取消订阅事件处理程序的好方法,因此A对象将与调用h()的B对象一样存在。Jon:我编辑了我的问题。请看编辑。顺便说一句,我买了你的书,也许你还记得我订书时告诉你的。所以,如果你在书中讨论过这件事,请务必告诉我这一章/章节,以便我自己详细阅读。@Nawaz:第二章有很多关于代表的内容,是的。享受:)哈哈……现在我正在看
2.2.2节,什么时候C#1的类型系统不够丰富?
。谢谢你写了这么好的一本书。也许你已经猜到这本书让我问了这个问题。也许,我应该有点耐心!最后一篇帖子……这告诉了我一些我一直在寻找的东西+1.