Does delegate assignment create a new copy in C #?

I read an article on C # and performance considerations ( here )

The article says that assigning a delegate causes memory allocation, for example:

each local variable assignment like "Func fn = Fn" creates a new instance of the Func delegate class on the heap

I wanted to know if this is true and if so - how is it implemented? I am not familiar with any way that referential assignment can cause additional memory allocation in C #.

+3


source to share


2 answers


The article is correct. Easy enough to check:

static void Main(string[] args)
{
    Action<string[]> main = Main;
    Action<string[]> main2 = Main;
    Console.WriteLine(object.ReferenceEquals(main, main2)); // False
}

      

http://ideone.com/dgNxPn

If you look at the IL code generated by http://goo.gl/S47Wfy , it's pretty clear what's going on:

    IL_0002: ldftn void Test::Main(string[])
    IL_0008: newobj instance void class [mscorlib]System.Action`1<string[]>::.ctor(object, native int)
    IL_000d: stloc.0
    IL_000e: ldnull

    IL_000f: ldftn void Test::Main(string[])
    IL_0015: newobj instance void class [mscorlib]System.Action`1<string[]>::.ctor(object, native int)
    IL_001a: stloc.1

      



So two newobj instance void class [mscorlib]System.Action

1 ::. ctor (object, native int) `

Note that you are correct that this is illogical:

public class TestEvent
{
    public event Action Event;

    public TestEvent()
    {
        Action d1 = Print;
        Action d2 = Print;

        // The delegates are distinct
        Console.WriteLine("d1 and d2 are the same: {0}", object.ReferenceEquals(d1, d2));

        Event += d1;
        Event -= d2;

        // But the second one is able to remove the first one :-)
        // (an event when is empty is null)
        Console.WriteLine("d2 was enough to remove d1: {0}", Event == null);
    }

    public void Print()
    {
        Console.WriteLine("TestEvent");
    }
}

      

For event

example, you can use an "equivalent but not the same" delegate to remove another delegate, as shown in the example. See https://ideone.com/xeJ6LO

+3


source


Obviously, you are declaring a new delegate instance and initializing it as such:

Func fn=new Func(Fn);  // hidden by syntactic sugar

      



However, the article is misleading about the higher memory usage, it is the same as the others, it just never got garbage collected because that is such a part of it.

0


source







All Articles