Когда лучше явно использовать ключевое слово делегат вместо лямбды? - PullRequest
3 голосов
/ 02 декабря 2009

Есть ли лучшая практика в отношении стиля кодирования в отношении явного использования ключевого слова delegate вместо использования лямбды?

, например

new Thread(() =>
{
    // work item 1
    // work item 2
}).Start();

new Thread(delegate()
{
    // work item 1
    // work item 2
}).Start();

Я думаю, что лямбда выглядит лучше. Если лямбда - лучший стиль, какой смысл иметь ключевое слово delegate, за исключением того факта, что оно существовало до того, как лямбды были внедрены?

1 Ответ

4 голосов
/ 02 декабря 2009

Синтаксис лямбда-выражений гораздо более обобщен, и дизайнеры заявили, что в идеале удалят старые перекрывающиеся синтаксисы (не цитируйте, но, вероятно, это Эрик Липперт или Джон Скит в книге или подкасте).

Но delegate позволяет игнорировать параметры, например ::1004

object.Event += delegate { };

против того, чтобы сказать:

object.Event += (sender,args) => { };

, что может быть очень полезно в больших списках аргументов и / или сделать код более устойчивым к рефакторингу.

РЕДАКТИРОВАТЬ: Как указал Янн Шварц в другом ответе (сейчас, к сожалению, удален), очень аккуратное использование этого трюка для обеспечения обработчика по умолчанию для события, используя шаблон Null Object: -

class MyClassThatFiresWithoutTheTrick
{
    public event EventHandler MyEvent; // implicit = null

    // Need a method to keep this DRY as each fire requires a null check - see Framework Design Guidelines by Abrams and Cwalina
    protected virtual void OnMyEvent()
    {
        // need to take a copy to avoid race conditions with _removes
        // See CLR via C# 3rd edition p 264-5 for reason why this happens to work
        //var handler = MyEvent;
        // BUT THIS is the preferred version
        var handler = Interlocked.CompareExchange( ref MyEvent, null, null);
        // Need to do this check as it might not have been overridden
        if( handler == null)
            return;
        handler( this, EventArgs.Empty );
    }
}

class MyClassThatFiresWithTheTrick
{
    public event EventHandler MyEvent = delegate{};

    protected virtual void OnMyEvent()
    {
        MyEvent( this, EventArgs.Empty );
    }
}

(хотя то, что вам часто приходится делать, это встроенный метод OnMyEvent, делающий код снова еще короче.)

...