Does a delegate assignment create a new copy in C#?

好久不见. 提交于 2020-08-07 06:56:42

问题


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

In the article, it is said that a delegate assignment triggers memory allocations, e.g:

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

I wanted to know if that is true, and if it is - how is that implemented? i am not familiar with any way that a reference assignment can trigger extra memory allocation in C#.


回答1:


The article is right. Quite easy to test:

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 http://goo.gl/S47Wfy, it is quite clear what happens:

    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 there are two newobj instance void class [mscorlib]System.Action1::.ctor(object, native int)`

Note that you are right that this is counterintuitive:

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");
    }
}

With events for 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




回答2:


Obviously, you're declaring a new instance of the delegate and initializing it as such:

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

However the article is misleading in regards to the higher memory usage, it's the same as the others, it just never got garbage collected because it's such a measly amount of it.



来源:https://stackoverflow.com/questions/30155153/does-a-delegate-assignment-create-a-new-copy-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!