Подтвердить что ты не робот

Почему lambdas может преобразовывать вызовы функций в Action?

В этом фрагменте кода:

List<String> names = new List<String>();
names.Add("Bruce");
names.Add("Tom");
names.Add("Tim");
names.Add("Richard");

names.ForEach(x => Print(x));

private static string Print(string s)
{
    Console.WriteLine(s);
    return s;
}

Print не является Action, так как он возвращает string; однако x=> Print(x) есть, почему?

4b9b3361

Ответ 1

Тип выражения лямбда x => Print(x) определяется на основе его контекста. Поскольку компилятор знает, что лямбда назначена Action<string>, компилятор игнорирует возвращаемый тип метода Print(s), как если бы это было выражение выражения.

Это допустимое преобразование:

Action<string> myAction = y => Print(y);

Другими словами, оба

Print("something");

и

int x = Print("something");

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

Ответ 2

x => Print(x) - это лямбда, которая превращается в метод, эквивалентный:

void MyPrintLambda(string x) { Print(x); }

Если бы контекст вызывал, скажем, a Func<string, string>, это было бы так:

string MyPrintLambda(string x) { return Print(x); }

Или, если это был Func<string, object>, это было бы так:

object MyPrintLambda(string x) { return Print(x); }

Поскольку компилятор может превратить x => Print(x) в Action<string>, просто игнорируя возвращаемый тип (т.е. первый пример), он может скомпилировать.

Ответ 3

По той же причине, что это было бы верно:

foreach (string name in names)
{
    Print(name);
}

Метод Print() возвращает значение в этом коде, но никто не ожидал, что это будет ошибка. Это позволило просто выбросить возвращаемое значение.