Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
381 views
in Technique[技术] by (71.8m points)

.net - Multicast delegate weird behavior in C#?

I have this simple event :

public class ClassA
{
    public event Func<string, int> Ev;
    public int Do(string l)
    {
        return Ev(l);
    }
}

And 2 Methods :

  static int Display(string k)
        {
            return k.Length;
        }

  static int Display_2(string k)
        {
            return k.Length*10;
        }

Im registering this event :

 ClassA a = new ClassA();
 a.Ev += Display;
 a.Ev += Display_2;

Now , I'm executing :

   Console.WriteLine(a.Do("aaa")); 

the output :

enter image description here

What ???

  • he has in invocation list 2 methods ! it did run them , but why does it shows only the result from the last registration ?

  • Where does the result of "3" has gone ? ( the first invocation ) ? ( although both display+display_2 was executed... I didn't expect console.write to iterate through results . but also didn't expect him to decide which to show.)

edit :

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are three aspects at play here:

  1. The implementation of the event
  2. The behaviour of delegate combination
  3. The behaviour of invoking a delegate whose invocation list has multiple entries

For point 1, you have a field-like event. Section 10.8.1 of the C# 4 spec gives an example, and states that:

Outside the declaration of the Button class, the Click member can be used only on the left-hand saide of the += and -= operators, as in

b.Click += new EventHandler(...);

which appends a delegate to the invocation list of the Click event

(emphasis mine). The spec also makes it clear that a field-like event creates a delegate field, which is used from within the class for invocation.

More generally (point 2), section 7.8.4 of the C# 4 spec talks about delegate combination via + and +=:

Delegate combination. Every delegate type implicitly provides the following predefined operator, where D is the delegate type:

D operator +(D x, D y)

The binary + operato performs delegate combination when both operands are of some delegate type D. [... skip bits where x or y are null ...] Otherwise, the result of the operation is a new delegate that, when invoked, invokes the first operand and then invokes the second operand.

(Again, emphasis mine.)

Finally, point 3 - event invocation and return values. Section 15.4 of the C# spec states:

If the delegate invocation includes output parameters or a return value, their final value will come from the invocation of the last delegate in the list.

More generally, it depends on the event implementation. If you use an event implementation which uses the "normal" delegate combination/removal steps, everything is guaranteed. If you start writing a custom implementation which does crazy things, that's a different matter.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...