2008-09-19 1 views
11

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

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

+0

Также см. [Whats-the-difference-between-anonymous-methods-and-lambda-expressions] (http://stackoverflow.com/questions/208381/whats-the-difference-between-anonymous-methods-c -2-0-и-лямбда-выражения) для общих различий. – nawfal 2014-07-03 11:30:07

ответ

8

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

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

может быть заменен

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

лямбда-выражений просто «синтаксический сахар», компилятор будет генерировать соответствующие делегатов для вас. Вы можете исследовать это, используя рефлектор Луца Родера.

+1

На самом деле лямбда-выражения немного больше, чем синтаксический сахар, поскольку они могут быть скомпилированы в дерево выражений и обработаны. – 2008-09-19 23:24:35

+0

Рефлектор теперь принадлежит redgate [http://www.red-gate.com/products/reflector/] – cori 2008-09-20 02:40:47

3

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

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

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

27

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

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

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“, потому что это не тип делегата».

+0

Я думаю, что вопросик спрашивает о том, что ключевое слово `delegate` устарело, в пользу нового синтаксиса на основе лямбда. Она объединяет «анонимных методов и делегатов» вместе. – nawfal 2013-12-20 10:02:44

3

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

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

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

7

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

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

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

  1. Трудно понять, для новых разработчиков
  2. менее объектно-ориентированного
  3. Гораздо труднее читать

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

+0

WOW !!! Я никогда не рассказываю об этом! Есть ли способ делать предикат, т. Е. Имена. Где (! String.IsNullOrEmpty)); ? Я пробовал, и это не работает для меня. Упс! Если я удалю! операнд, он действительно работает, почему ??? Я даже попытался поставить его в круглые скобки, но он не может вызвать его вообще, есть ли способ? Мы на самом деле пытаемся преобразовать string.IsNullOrEmpty в string.IsNotNullOrEmpty ... – Shimmy 2009-07-23 04:53:56

2

Один не очень большой Преимущество синтаксиса старшего 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.

Смежные вопросы