在.NET中,当你有一个只有一个空方法的委托订阅它时,.NET VM是否意识到这一点并且甚至不会调用它?
我问,因为我注意到,当您订阅一次时,调用计数设置为2,但是当您取消订阅时,该值将下降到0(而不是1)。
答案 0 :(得分:5)
不,你看到的是MulticastDelegate类,它优化了只有一个目标方法的一般情况。只有一个,它可以将目标存储在基类'(Delegate)_methodBase和_target字段中。
当存在多个目标时,必须创建一个列表来存储目标。现在它使用_invocationList字段,因此它可以根据需要存储任意数量的目标。换句话说,_invocationCount将从不为1。
您可以通过在调试器中扩展“base”来看到这一点。
答案 1 :(得分:2)
不,就我所知,仍然会调用一个空的但非空的委托。
关于您的取消订阅:请提供一些示例代码。 (我将在一分钟内提供显示相反的示例代码。)
using System;
class Test
{
static void Main()
{
Action action = EmptyMethod;
Console.WriteLine(action.GetInvocationList().Length);
action += NonEmptyMethod;
action -= NonEmptyMethod;
Console.WriteLine(action.GetInvocationList().Length);
}
static void EmptyMethod() {}
static void NonEmptyMethod()
{
Console.WriteLine("Testing");
}
}
这只打印1次 - 在订阅/取消订阅周期之前和之后显示一个“空”处理程序。
我确信当您发布一个显示您的意思的类似示例时,我们将能够轻松地解释您的结果。
答案 2 :(得分:0)
EventHandler del = null;
EventHandler subscriber2 = delegate { Console.WriteLine("Subscriber2");};
del += delegate { };
Console.WriteLine(del.GetInvocationList().Length);
del += subscriber2;
Console.WriteLine(del.GetInvocationList().Length);
del(null, null);
del -= subscriber2;
Console.WriteLine(del.GetInvocationList().Length);
输出:
1
2
Subscriber2
1