>>>Thx - very interesting to see that they varied the algorithm depending on the context
>>>Nice to know I was right (although I admit that after considering your initial post I thought I was wrong ) :-}
>>
>>Well, my initial post made sense to me as well - just did not consider the compiler trickery
>>
>>In the case of integers, it works as I thought (there's no Concat there)
>>
>>I cannot think of a good reference type that implements the operator +, so I cannot check.
>>
>>Did a check with the reference type delegate
>>
>>Interesting- aside from the fact that it calls delegate.Combine() 3 times -
>>
>>Each time a method is used ( xx, yy, zz) to add to the delegate, it loads the reference to the function, calls a delegate constructor with the function as a parameter, and then calls Combine which accepts two delegates.
>>
>>When I look at the signatures of Delegate.Combine
http://msdn.microsoft.com/en-us/library/b1eh4771.aspx there is also Delegate.Combine( Delegate[]) and it does not use that
>>
>>
>> delegate void TheDelegate ( int i );
>> class Program
>> {
>>
>>
>>
>>
>> static void xx(int i)
>> {
>> }
>>
>> static void yy(int i)
>> {
>> }
>>
>> static void zz(int i)
>> {
>> }
>> static void Main(string[] args)
>> {
>>
>> TheDelegate chain = null ;
>> chain = chain + xx + yy + zz;
>>
>>
>> return;
>> }
>> }
>>
>>
>>listing
>>
>>.method private hidebysig static void Main(string[] args) cil managed
>>{
>> .entrypoint
>> // Code size 74 (0x4a)
>> .maxstack 4
>> .locals init ([0] class CoreTest.TheDelegate chain)
>> IL_0000: nop
>> IL_0001: ldnull
>> IL_0002: stloc.0
>> IL_0003: ldloc.0
>> IL_0004: ldnull
>> IL_0005: ldftn void CoreTest.Program::xx(int32)
>> IL_000b: newobj instance void CoreTest.TheDelegate::.ctor(object,
>> native int)
>> IL_0010: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,
>> class [mscorlib]System.Delegate)
>> IL_0015: castclass CoreTest.TheDelegate
>> IL_001a: ldnull
>> IL_001b: ldftn void CoreTest.Program::yy(int32)
>> IL_0021: newobj instance void CoreTest.TheDelegate::.ctor(object,
>> native int)
>> IL_0026: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,
>> class [mscorlib]System.Delegate)
>> IL_002b: castclass CoreTest.TheDelegate
>> IL_0030: ldnull
>> IL_0031: ldftn void CoreTest.Program::zz(int32)
>> IL_0037: newobj instance void CoreTest.TheDelegate::.ctor(object,
>> native int)
>> IL_003c: call class [mscorlib]System.Delegate [mscorlib]System.Delegate::Combine(class [mscorlib]System.Delegate,
>> class [mscorlib]System.Delegate)
>> IL_0041: castclass CoreTest.TheDelegate
>> IL_0046: stloc.0
>> IL_0047: br.s IL_0049
>> IL_0049: ret
>>} // end of method Program::Main
>>
>
>Interesting again - but there doesn't seem to be any optimization there ? From
http://msdn.microsoft.com/en-us/library/system.delegate.aspx:>"Combining operations, such as Combine and Remove, do not alter existing delegates. Instead, such an operation returns a new delegate that contains the results of the operation, an unchanged delegate, or Nothing"
No, no optimization - maybe with a bigger number it may end up calling Delegate.Combine( Delegate[] )
- The Combine method leaves a new delegate on the stack - it's all in the listing - followed by a cast
- The intermediate results are left on the stack, only the last result is stored ( IL_0046: stloc.0 )
>Then again, since I can count the number of times I've used a Multicast delegate on the fingers of one elbow I'm not too worried :-}
>Actually something like this did come up the other day and I started thinking about using MEF as an alternative to multicast delegates...
Gregory