#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
}
}