лямбда -> делегат не компилируется

#c# #.net #delegates #lambda #action

#c# #.net #делегаты #лямбда — выражение #Экшен #лямбда

Вопрос:

Последнее утверждение не компилируется. пожалуйста, обратитесь к комментариям вместе с кодом для получения подробной информации по моему вопросу.

 class Test
{
    private static void Foo(Delegate d){}

    private static void Bar(Action a){}

    static void Main()
    {
        Foo(new Action(() => { Console.WriteLine("a"); })); // Action converts to Delegate implicitly

        Bar(() => { Console.WriteLine("b"); }); // lambda converts to Action implicitly

        Foo(() => { Console.WriteLine("c"); }); // Why doesn't this compile ? (lambda converts to Action implicitly, and then Action converts to Delegate implicitly)
    }
}
  

Комментарии:

1. Рассмотрите возможность включения сообщений об ошибках компилятора в сообщение. Это поможет в поиске, а также в контексте (для людей, которые раньше не сталкивались с такой ситуацией) — и подумайте о том, чтобы сделать заголовок релевантным для вопроса 🙂 [Гуманизированная форма сообщения об ошибке должна быть хорошей отправной точкой для заголовка]

2. у меня все еще есть другой вопрос: у нас уже есть lambda и Action, Func<T> , зачем нам все еще нужен delegate? Если нет такой вещи, как делегирование, не будет такой досадной проблемы.

Ответ №1:

Потому что компилятор .net не знает, в какой тип делегата преобразовать лямбда. Это может быть действие, или это может быть void MyDelegate() .

Если вы измените это следующим образом, это должно сработать:

 Foo(new Action(() => { Console.WriteLine("c"); }));
  

Комментарии:

1. или создайте private delegate void FooDelegate(); и используйте его.

Ответ №2:

Почему компилятор должен знать, как выполнить двухэтапный переход: из лямбда -> Действие -> Делегировать?

Это компилирует:

 class Test
{
    private static void Foo(Delegate d) { }

    private static void Bar(Action a) { }

    static void Main()
    {
        Foo(new Action(() => { Console.WriteLine("world2"); })); // Action converts to Delegate implicitly

        Bar(() => { Console.WriteLine("world3"); }); // lambda converts to Action implicitly

        Foo((Action)(() => { Console.WriteLine("world3"); })); // This compiles
    }
}