委托分配是否在C#中创建新副本? [英] Does a delegate assignment create a new copy in C#?
问题描述
我阅读了有关C#和性能注意事项的文章(此处)
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:
每个单个局部变量赋值,例如"Func fn = Fn" 在堆上创建委托类Func的新实例
every single local variable assignment like "Func fn = Fn" creates a new instance of the delegate class Func on the heap
我想知道那是否是真的,那是如何实现的?我不熟悉引用分配可以触发C#中的额外内存分配的任何方式.
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#.
推荐答案
本文正确.很容易测试:
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
}
如果您查看生成的IL代码 http://goo.gl/S47Wfy ,这很清楚会发生什么:
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
所以有两个 newobj instance void class [mscorlib]System.Action
1 ::.ctor(对象,本机int)`
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");
}
}
例如,对于event
,您可以使用等效但不相同"的委托删除另一个委托,如示例所示.参见 https://ideone.com/xeJ6LO
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
这篇关于委托分配是否在C#中创建新副本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!