ключевое слово делегата по сравнению с нотацией лямбды

178
задан abatishchev 7 October 2011 в 12:18
поделиться

4 ответа

Короткий ответ: нет.

Более длинный ответ, который не может быть релевантным:

  • при присвоении лямбды типу делегата (такой как Func или Action) Вы получите анонимного делегата.
  • при присвоении лямбды Типу выражения Вы получите дерево выражений вместо анонимного делегата. Дерево выражений может тогда быть скомпилировано в анонимного делегата.

Редактирование: вот некоторые ссылки для Выражений.

  • Система. Linq. Выражение. Выражение (TDelegate) (запускаются здесь).
  • Linq, в оперативной памяти с делегатами (такими как Система. Func) использование Система. Linq. Счетный . Linq к SQL (и что-либо еще) с использованием выражений Система. Linq. Queryable. Проверьте параметры на те методы.
  • Объяснение от ScottGu. Короче говоря Linq, в оперативной памяти, произведет некоторые анонимные методы для разрешения запроса. Linq к SQL произведет дерево выражений, которое представляет запрос, и затем переведите то дерево в T-SQL. Linq к Объектам произведет дерево выражений, которое представляет запрос, и затем переведите то дерево в платформу соответствующий SQL.
139
ответ дан Amy B 23 November 2019 в 20:16
поделиться

David B корректен. Обратите внимание, что могут быть преимущества для использования деревьев выражений. LINQ к SQL исследует дерево выражений и преобразует его в SQL.

можно также выделывать фокусы с lamdas и деревьями выражений для эффективной передачи имен участников класса к платформе безопасным от рефакторинга способом. Moq является примером этого.

2
ответ дан Amy B 23 November 2019 в 20:16
поделиться

Мне нравится ответ David, но я думал, что буду педантичен. Вопрос говорит, "Как только он компилируется" - который предлагает, чтобы оба выражения имели скомпилированный. Как они могли и скомпилировать, но с одним преобразовываемым в делегата и один к дереву выражений? Это - хитрое - необходимо использовать другую функцию анонимных методов; единственный, который не совместно используется лямбда-выражениями. При определении анонимного метода, не определяя список параметров во всем , это совместимо с любым возвратом типа делегата пусто и без любого out параметры. Вооруженный этим знанием, нам необходимо создать две перегрузки для создания выражений абсолютно однозначными, но очень отличающимися.

, Но забастовки бедствия! По крайней мере, с C# 3.0, Вы не можете преобразовать лямбда-выражение с телом блока в выражение - и при этом Вы не можете преобразовать лямбда-выражение с присвоением в теле (даже если это используется в качестве возвращаемого значения). Это может измениться с C# 4.0 и.NET 4.0, которые позволяют больше быть выраженным в дереве выражений. Так, другими словами, с примерами MojoFilter, оказалось, дал, эти два будут [почти 115] всегда преобразовываться в то же самое. (Больше деталей за минуту.)

Мы можем использовать прием параметров делегата, если мы изменяем тела немного хотя:

using System;
using System.Linq.Expressions;

public class Test
{
    static void Main()
    {
        int x = 0;
        Foo( () => x );
        Foo( delegate { return x; } );
    }

    static void Foo(Func<int, int> action)
    {
        Console.WriteLine("I suspect the anonymous method...");
    }

    static void Foo(Expression<Func<int>> func)
    {
        Console.WriteLine("I suspect the lambda expression...");
    }
}

, Но ожидают! Мы можем дифференцироваться между двумя даже, не используя деревья выражений, если мы - достаточно хитрость. Пример ниже использует правила разрешения перегрузки (и анонимный делегат, соответствующий приему)...

using System;
using System.Linq.Expressions;

public class Base
{
    public void Foo(Action action)
    {
        Console.WriteLine("I suspect the lambda expression...");
    }
}

public class Derived : Base
{
    public void Foo(Action<int> action)
    {
        Console.WriteLine("I suspect the anonymous method...");
    }
}

class Test
{
    static void Main()
    {
        Derived d = new Derived();
        int x = 0;
        d.Foo( () => { x = 0; } );
        d.Foo( delegate { x = 0; } );
    }
}

Ай. Помните детей, каждый раз, когда Вы перегружаете метод, наследованный от базового класса, немного котенка начинает кричать.

125
ответ дан Amy B 23 November 2019 в 20:16
поделиться

В этих двух примерах выше нет никакого различия, нуля.

выражение:

() => { x = 0 }

Лямбда-выражение с телом оператора, таким образом, оно не может быть скомпилировано как дерево выражений. На самом деле это даже не компилирует, потому что этому нужна точка с запятой после 0:

() => { x = 0; } // Lambda statement body
() => x = 0      // Lambda expression body, could be an expression tree. 
2
ответ дан Matthew 23 November 2019 в 20:16
поделиться
Другие вопросы по тегам:

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