C# compiler oddity with delegate constructors?

The spec (section 7.6.10.5) says: The new delegate instance is initialized with the same invocation list as the delegate instance given by E. Now suppose the compiler translated it to something similar to your suggestion of: new Action( a. Target, a.

Method) That would only ever create a delegate with an invocation list of a single method call. For a multi-cast delegate, it would violate the spec. Sample code: using System; class Program { static void Main(string args) { Action first = () => Console.

WriteLine("First"); Action second = () => Console. WriteLine("Second"); Action both = first + second; Action wrapped1 = (Action) Delegate. CreateDelegate(typeof(Action), both.

Target, both. Method); Action wrapped2 = new Action(both); Console. WriteLine("Calling wrapped1:"); wrapped1(); Console.

WriteLine("Calling wrapped2:"); wrapped2(); } } Output: Calling wrapped1: Second Calling wrapped2: First Second As you can see, the real behaviour of the compiler matches the spec - your suggested behaviour doesn't. This is partly due to the somewhat odd "sometimes single-cast, sometimes multi-cast" nature of Delegate, of course...

Wait, that text is confusing. The new delegate will just be a wrapper, and will only have a single item in the invocation list. Else everything would be called twice.

– leppie Nov 10 at 10:33 I can see however that multicast delegates makes this a complex scenario. – leppie Nov 10 at 10:35 Console. WriteLine(wrapped2.

GetInvocationList(). Length); prints 1. The spec is violated (or just incorrectly specified).

– leppie Nov 10 at 10:38 @leppie: It depends on whether you view "the invocation list" as simply "the methods which end up being invoked when the delegate is invoked" or the implementation details (with GetInvocationList etc). I think if you rely on just what's in the spec, the compiler behaviour is consistent. – Jon Skeet Nov 10 at 10:38 It would have been clearer if it stated: 'The new delegate instance simply calls Invoke on the delegate given as E'.

– leppie Nov 10 at 10:40.

When you try to treat a delegate as a method, the compiler actually uses the delegate's Invoke() method. So, for example, the two lines below compile to the exact same IL (both call Invoke()): k(); k.Invoke(); I assume the oddity you're seeing is a consequence of this. The delegate constructor expects a method (or rather, a method group), but it gets a delegate instead.So it treats it as a method and uses the Invoke() method.

As for the meaning, it is delegate that calls delegate that calls the actual method. You can verify this yourself by accessing the delegate's Method and Target properties.In the case of the outer-most delegate, Method is Action. Invoke and Target the inner delegate.

I kinda follow, but this design makes delegates more of a second class citizen. Like in some context k is really k. Invoke, but in other cases k is just a delegate.

– leppie Nov 10 at 10:28 I think that's because delegates are actually (almost) normal classes, as far as the CLR is concerned. To make them first-class citizen in C#, you have to resort to things like this. – svick Nov 10 at 10:47 Normal classes are first class citizens, providing some magic functionality makes them second class (well that specific functionality).

– leppie Nov 10 at 10:51.

Delegate is a class Action delegate has a constructor like so public extern Action(object @object, IntPtr method); Since K is a static method there is no need to pass object to inner most action instance as first argument and hence it passes null Since second argument is pointer to function therefore it passes pointer of K method using ldftn function for the remaining Action instances the object is passed is inner Action and the second parameter is the Invoke method since when you call a delegate you're actually calling the Invoke method Summary var action = new Action(K) => Action action = new Action(null, ldftn(K)) new Action(action) => new Action(action, ldftn(Action. Invoke)) I hope this explains what is happening?

The question I ask is exactly what you say in your last point. I know what is happening, but why? – leppie Nov 10 at 10:12 @leppie check updated answer – Hasan Khan Nov 10 at 10:18 If you read my question again, you will notice everything you say is already there.

I understand what is happening. I want to know what the justification (or the why) for this. – leppie Nov 10 at 10:19 1 @leppie how else should compiler transform your code?

There is no such thing as new Action(blah) in MSIL. C# just provides you syntatic sugar. Its like asking why var i=3 is same as int i= 3 – Hasan Khan Nov 10 at 10:22.

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions