Вопрос по c#, anonymous-methods, lambda, .net-3.5, delegates – Есть ли случай, когда синтаксис делегата предпочтительнее, чем лямбда-выражение для анонимных методов?

12

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

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

Также смwhats-the-difference-between-anonymous-methods-and-lambda-expressions для общих отличий. nawfal

Ваш Ответ

7   ответов
3

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

На самом деле лямбда-выражения - это нечто большее, чем синтаксический сахар, поскольку их можно скомпилировать в дерево выражений и манипулировать ими.
Отражатель теперь принадлежит Redgate [red-gate.com/products/reflector/]
4

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

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

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

2

Одинnot so big преимущество для пожилыхdelegate Синтаксис заключается в том, что вам не нужно указывать параметры, если вы не используете их в теле метода. ОтMSDN

There is one case in which an anonymous method provides functionality not found in lambda expressions. Anonymous methods enable you to omit the parameter list. This means that an anonymous method can be converted to delegates with a variety of signatures. This is not possible with lambda expressions.

Например, вы можете сделать:

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"); };

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

На самом деле я искал сценарий использования с раннего утра сегодня, чтобы выяснить, почему я должен указывать аргумент в сигнатуре метода, но не использовать его в теле метода: P. Обработчики событий кажутся примером, но все же1, Пропуск параметров добавляет путаницы.2, Завтра, если я буду нуждаться в использовании любого изobject sender, EventArgs e параметры, то разработчик должен знать об этом конкретном приеме компилятора, который не так очевиден. Для меня это большой палец вниз с точки зрения возможностей, просто чтобы сохранить два слова ввода. Я полностью согласен с вами вThis is not a strong advantage
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 ". потому что это не тип делегата & quot ;.

Я думаю, что спрашивающий спрашивает оdelegate Ключевое слово устарело, в пользу более нового лямбда-синтаксиса. Она группирует «анонимные методы и делегаты»; все вместе.
7

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

List<string> names = GetNames();
names.ForEach(Console.WriteLine);
it makes code more readable thus simple to understand. It makes code shorter thus less work for us ;)

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

Hard to understand for new developers Less object oriented Much harder to read

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

ВОТ ЭТО ДА!!! Я никогда не кричу об этом! Есть ли способ сделать предикат тоже, то есть names.Where (! String.IsNullOrEmpty)); ? Я пытался, и это не работает для меня. К сожалению! Если я удалю! операнд это работает, почему ??? Я даже пытался поместить его в скобки, но он не может вызвать его вообще, есть ли способ? На самом деле мы пытаемся преобразовать string.IsNullOrEmpty в string.IsNotNullOrEmpty ...
8

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

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

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

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

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

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

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

Похожие вопросы