Будет ли пустой делегат съедать память?

public sealed class FtpManager
{
    public event EventHandler LoggingIn = delegate { };
    private void OnLoggingIn(object sender, EventArgs e)
    {
        var handler = LoggingIn;
        handler(sender, e);
    }
// ...
}

В приведенном выше коде я инициализировал обработчик событий LoggingIn с пустым делегатом.

Будет ли это влиять на пространство памяти, используемое каким-либо образом? Особенно, когда сотни или тысячи событий объявлены таким образом?

Ответы

Ответ 1

Поцарапайте предыдущий ответ (ниже для потомков). Это зависит от реализации компилятора, но в текущем компиляторе MS С# 3.0 это фактически создает только один экземпляр, который повторно используется для каждого экземпляра. Он может это сделать, потому что делегаты являются неизменными и что делегат не требует никакой информации из экземпляра.

Я не знаю, было ли это в случае с С# 2.0. Вы можете декомпилировать свой код и посмотреть, действительно ли IL использует кешированное поле или нет. Использование приведенного ниже ответа является безопасным способом гарантировать, что вы создадите только один экземпляр.

Оригинальный ответ:

Да, он создает экземпляр делегата. Это потребует некоторой памяти. Вы могли бы уменьшить это, хотя:

public static class EventHandlers
{
    public static readonly EventHandler Empty = delegate {};
}

public sealed class FtpManager
{
    public event EventHandler LoggingIn = EventHandlers.Empty;
}

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

Ответ 2

Альтернативой этому является проверка LoggingIn для nullity каждый раз, когда вы хотите его поднять. Это может быть более интенсивным, чем вызов пустого делегата.