问题
Follow up to my question here:
According to a comment made -
The compiler creates a class member with a fictitious name and attaches it just as you would attach a declared method.
I do not fully comprehend what this means but I can verify that if instead of saying
Foo.Bar += (S, E) => { /*Code Goes Here*/ }
I instead say
Foo.Bar += FooBar;
private void FooBar( object sender, EventArgs e ){
/*Code Goes Here*/
}
then Event.Target
changes from WhatIsThis.App.<>c
to WhatIsThis.App
.
That's awesome but I can't guarantee that I will always write an actual method to attach to an event handler.
In the cases where I do use an anonymous method, is there a way to extract the real target, or am I just pigeonholed into using defined methods (I mean, I can live with that I guess but if there's some high-tech sorcery that I can employ to extract the real target, then I'm all for it ).
回答1:
do not fully comprehend what this means
Let's fix your comprehension. Suppose you have:
class C
{
int x;
void M(int y)
{
int z = GetZ();
Func<int, int> f = q => q + x + y + z;
...
f is a delegate. It has a receiver and a method that is a method of the receiver. (Note, this is not actually a strict requirement but the corner case is obscure for our purposes today.)
What type is the receiver that has that method?
Can it be C, with the receiver equal to this
? No. Why not? Because then how do we keep track of the value of y and z? There could be a different value for every invocation of M, so the receiver cannot be this
.
What the compiler does is generates a new class:
class C
{
int x;
class Locals
{
public C __this;
public int y;
public int z;
public int A(int q) { return q + __this.x + y + z; }
}
void M(int y)
{
Locals locals = new Locals();
locals.__this = this;
locals.y = y;
locals.z = GetZ();
Func<int, int> f = locals.A;
...
So what is the receiver? the value of locals. What is the method? A.
Of course both Locals and A are given crazy names so that you cannot call them by accident.
In the cases where I do use an anonymous method, is there a way to extract the real target
You are extracting the real receiver, I promise.
'm working on an extension to do some things with Event Handlers and I need to be able to discern what an event handlers target is
Please don't do that. The receiver of an event handler is an implementation detail of the code that provided the handler. It's not there for you to make decisions on. Compilers are well within their rights to make any choice they like when generating a receiver for an event handler, and they do. Consider what happens if the event handler was created inside an iterator block, or an async method, for example. Or the event is being subscribed by some reactive extensions code that is applying sequence operations to the event. Again, the compiler will be generating classes all over the place. You can't rely on the class being something "sensible".
The thing you can rely on is: the subscriber wished the given method to be called when something happened. That's the contract you must obey; don't try to second-guess the subscriber.
来源:https://stackoverflow.com/questions/35759749/how-can-i-extract-the-real-target-from-an-event-handler-that-was-defined-anony