Есть ли случай, когда синтаксис делегата предпочтительнее выражения лямбда для анонимных методов?

С появлением новых функций, таких как лямбда-выражения (встроенный код), означает ли это, что нам больше не нужно использовать делегаты или анонимные методы? Почти во всех образцах, которые я видел, он предназначен для перезаписи с использованием нового синтаксиса.

Любое место, где мы все еще должны использовать делегаты и лямбда-выражения, не будет работать?

Ответ 1

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

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

public static void Invoke(Delegate d)
{
  d.DynamicInvoke();
}

static void Main(string[] args)
{
  // fails
  Invoke(() => Console.WriteLine("Test"));

  // works
  Invoke(new Action(() => Console.WriteLine("Test")));

  Console.ReadKey();
}

Ошибка строки кода получит ошибку компилятора "Невозможно преобразовать лямбда-выражение в тип" System.Delegate ", потому что это не тип делегата".

Ответ 2

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

 delegate(int i) { Console.WriteLine(i.ToString()) }

можно заменить на

f => Console.WriteLine(f.ToString())

Ответ 3

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

List<string> names = GetNames();
names.ForEach(Console.WriteLine);
  • он делает код более читаемым, поэтому его легко понять.
  • Это делает код короче, поэтому для нас меньше работы;)

С другой стороны, очень просто злоупотреблять ими. Длинные или/и сложные лямбда-выражения имеют тенденцию быть:

  • Трудно понять для новых разработчиков
  • Меньше объектно-ориентированных
  • Намного сложнее читать

Итак, означает ли это, что нам больше не нужно использовать делегатов или анонимные методы? " Нет - использовать выражение Lambda, где вы выигрываете время/удобочитаемость, иначе подумайте об использовании делегатов.

Ответ 4

Лямбда-выражения - это просто "синтаксический сахар", компилятор будет генерировать для вас соответствующие делегаты. Вы можете исследовать это с помощью рефлектора Lutz Roeder Reflector.

Ответ 5

Lamda - это просто синтаксический сахар для делегатов, они не просто встроены, вы можете сделать следующее:

s.Find(a =>
{
    if (a.StartsWith("H"))
        return a.Equals("HI");
    else
        return !a.Equals("FOO");
});

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

Ответ 6

Делегат имеет два значения в С#.

Ключевое слово delegate может использоваться для определения типа сигнатуры функции. Обычно это используется при определении подписи функций более высокого порядка, т.е. Функций, которые принимают другие функции в качестве аргументов. Это использование делегата по-прежнему актуально.

Ключевое слово delegate также может использоваться для определения встроенной анонимной функции. В случае, когда функция является всего лишь одним выражением, синтаксис лямбда является более простой альтернативой.

Ответ 7

Не слишком большое преимущество для более старого синтаксиса delegate заключается в том, что вам не нужно указывать параметры, если вы не используете его в теле метода. Из msdn

Существует один случай, когда анонимный метод обеспечивает функциональность не найдено в лямбда-выражениях. Анонимные методы позволяют вам опустить список параметров. Это означает, что анонимный метод может быть преобразуется в делегатов с множеством подписей. Это не возможно с лямбда-выражениями.

Например, вы можете:

Action<int> a = delegate { }; //takes 1 argument, but not specified on the RHS

Пока это не удается:

Action<int> a = => { }; //omitted parameter, doesnt compile.

Этот метод в большинстве случаев удобен при написании обработчиков событий, например:

button.onClicked += delegate { Console.WriteLine("clicked"); };

Это не сильное преимущество. Лучше использовать новый синтаксис всегда imho.