2010-07-29 58 views
1

在.NET中,当你有一个只有订阅了空方法的委托时,.NET VM是否意识到这一点并跳过甚至调用它?空的委托不被调用吗?

我在问,因为我注意到,当您订阅一次,但是当您取消订阅它时,调用计数设置为2,值将降为0(不是1)。

回答

5

不,你看到的是MulticastDelegate类优化,其中有只有一个目标方法的一般情况。只有一个,它可以将目标存储在基类'(委托)_methodBase和_target字段中。

当有不止一个时,它必须创建一个列表来存储目标。现在它使用它的_invocationList字段,因此它可以根据需要存储尽可能多的目标。换句话说,_invocationCount将从来没有是1.

你可以通过在调试器中展开“base”来看到这一点。

+1

啊,内部字段值的错误解读的乐趣。通过'GetInvocationList()'*计算调用计数*会返回1,当然:) – 2010-07-29 10:21:44

2

不,空,但非null的委托仍然会被调用,据我所知。

关于您的取消订阅:请提供一些示例代码。 (我将提供显示在一分钟内反向的代码示例。)

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两次 - 表示前和订阅/取消循环后一个单一的“空”的处理程序。

我敢肯定,当你发布了一个类似的例子来展示你的意思时,我们可以很容易地解释你的结果。

+0

Skeeted再次:) ...恭喜200K - 励志。 – Gishu 2010-07-29 10:08:06

+0

@Gishu:我现在还不到200K。另外166去。我怀疑明天会发生什么...... – 2010-07-29 10:21:03

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