问题
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.Action
1::.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 event
s 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