Пустых делегатов не вызывают? - PullRequest
1 голос
/ 29 июля 2010

В .NET, если у вас есть делегат, у которого подписан только пустой метод, понимает ли это .NET VM и пропускает даже его вызов?

Я спрашиваю, потому что я заметил, что счетчик вызовов установлен в 2, когда вы подписываетесь один раз, но когда вы отмените его, значение уменьшается до 0 (не 1).

Ответы [ 3 ]

5 голосов
/ 29 июля 2010

Нет, вы видите класс MulticastDelegate, оптимизирующий общий случай, когда есть только один целевой метод.При наличии только одного он может хранить цель в полях базового класса '(Delegate) _methodBase и _target.

Если их несколько, необходимо создать список для хранения целей.Теперь он использует свое поле _invocationList, поэтому может хранить столько целей, сколько необходимо.Другими словами, _invocationCount будет никогда равным 1.

Это можно увидеть, расширив «base» в отладчике.

2 голосов
/ 29 июля 2010

Нет, насколько мне известно, пустой, но ненулевой делегат будет по-прежнему вызываться.

Что касается вашей отписки: предоставьте пример кода.(Я предоставлю пример кода, показывающего обратное через минуту.)

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 голосов
/ 29 июля 2010
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
...