[英]On what instance of class delegate gets invoked?
Consider this code, 考虑一下这段代码
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();
}
}
}
In this code snippet, SomeEvent.invoke()
actually invokes SomeMethod()
of class A
. 在这段代码片段中,
SomeEvent.invoke()
实际上调用了A
类的SomeMethod()
。 So at this point, I've few questions: 所以在这一点上,我几乎没有问题:
A
, SomeMethod
gets invoked? A
, SomeMethod
被调用? How does B
know the instance on which the delegate to be invoked? B
如何知道要调用委托的实例? How does CLR work here? SomeMethod
is a private method, then how come B
is able to invoke this method from outside of the class A
? SomeMethod
是一个私有方法,那么为什么B
能够从A
类外部调用这个方法呢? EDIT: 编辑:
After reading first few answers, I came to know that Delegate
has a Target
property on which delegate gets invoked. 在阅读了前几个答案之后,我开始知道
Delegate
有一个Target
属性,在该属性上调用了委托。 But I couldn't really understand as to at exactly what step this Target
property is set? 但我真的不明白这个
Target
属性到底是什么步骤? Who set it? 是谁设定的? When I write
b.SomeEvent += this.SomeMethod;
当我写
b.SomeEvent += this.SomeMethod;
, does it set the Target
property as well? ,它是否也设置了
Target
属性? How exactly? 究竟怎么样?
b.SomeEvent += this.SomeMethod
There's a lot of sugar here that prevents you from seeing what is really happening. 这里有很多糖会阻止你看到真正发生的事情。 Written out, it resembles this:
写出来,它类似于:
b.SomeEvent.add(new MulticastDelegate(this, SomeMethod)); // not legal code
Where add() is the add accessor for the event, the compiler auto-generates one when you don't declare your own explicitly. 其中add()是事件的add访问器,当您没有显式声明自己的访问器时,编译器会自动生成一个。 The first argument to the delegate constructor is the object instance that you are asking about, the delegate object's Target property.
委托构造函数的第一个参数是您要询问的对象实例,即委托对象的Target属性。 Note that this has side-effects, the event subscription keeps a reference to your
b
object. 请注意,这会产生副作用,事件订阅会保留对
b
对象的引用。 Which prevents it from getting garbage collected, that would be rather bad when the event is invoked. 这可以防止它被垃圾收集,这在调用事件时会相当糟糕。
That can also be a problem, you can unintentionally leak the object reference. 这也可能是一个问题,你可以无意中泄漏对象引用。 There's no good way in your code to un-subscribe the event handler so the A object is going to live as long as the B object on which you called h().
在代码中没有好的方法来取消订阅事件处理程序,因此只要你调用h()的B对象,A对象就会生存。
The delegate contains the target reference to call the method on. 委托包含调用方法的目标引用。 You can examine this with the
Delegate.Target
property. 您可以使用
Delegate.Target
属性进行检查。 In this case it will be called on the instance which f
is called on. 在这种情况下,它将在调用
f
的实例上调用。 (It's null if you're calling a static method.) (如果您正在调用静态方法,则为null。)
As for the privacy - that's just one of the features of delegates. 至于隐私 - 这只是代表的一个特点。 You can only create the delegate within code which has access to a private method, but you can run it anywhere.
您只能在有权访问私有方法的代码中创建委托,但您可以在任何地方运行它。 Think of this as being like implementing an interface by just calling a private method from the public interface implementation.
可以认为这就像通过从公共接口实现调用私有方法来实现接口一样。
On what instance of A, SomeMethod gets invoked?
在什么实例的A,SomeMethod被调用? How does B know the instance on which the delegate to be invoked?
B如何知道要调用委托的实例? How does CLR work here?
CLR如何在这里工作?
The delegate actually contains a reference to the actual instance. 委托实际上包含对实际实例的引用。 This will cause it to invoke on the specific instance on which it was called.
这将导致它在调用它的特定实例上调用。
Also, SomeMethod is a private method, then how come B is able to invoke this method from outside of the class A?
另外,SomeMethod是一个私有方法,那么为什么B能够从A类外部调用这个方法呢?
It doesn't execute the method directly - it executes the delegate . 它不直接执行方法 - 它执行委托 。 There's a difference here - the private constraint only applies to the method, but since the class itself creates the delegate, it has access to the method, so everything works fine.
这里有一点不同 - 私有约束仅适用于该方法,但由于类本身创建了委托,因此它可以访问该方法,因此一切正常。
A
passed a delegate representation to it outside of the class. A
在类之外传递了委托表示。 A particular Delegate
instance has a Target
property; 特定的
Delegate
实例具有Target
属性; this represents the instance that will be used when invoking the delegate. 这表示调用委托时将使用的实例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.