Вывод типа в C # является очень сложным - на этот раз я не собираюсь выдвигать спецификацию, чтобы попытаться пройти через нее, потому что я осознаю, насколько ужасной она может стать.
Я считаю проблема в том, что ни одна из комбинаций параметров / аргументов не дает компилятору достаточно информации для вывода T
:
-
TEnumerable items
параметр не упоминает T
, поэтому он не используется для вывода T
, несмотря на ограничение типа - Параметр
Action<T>
будет в порядке, но компилятор не может сделать вывод на основев лямбда-выражении, которое вы предоставляете
Я не могу придумать хорошего изменения сигнатуры метода, которое сделало бы точно вашей первой работой кода - но вы можете изменить способВы вызываете метод просто немного , чтобы заставить его работать, указав тип параметра в лямбда-выражении:
var list = new List<int>();
list.WithEach((int x) => Console.WriteLine(x++))
.OrderBy(x => x)
.WithEach((int x) => Console.WriteLine(x));
Недостатком этого является то, что он не будет работать с анонимнымтипы, конечно.
одинОбходной путь для этого недостатка довольно ужасный, но он позволяет вместо этого выражать тип T
через параметр, когда это необходимо.Вы можете изменить сигнатуру метода на:
public static TEnumerable WithEach<TEnumerable, T>(
this TEnumerable items,
Action<T> action,
T ignored = default(T))
Если вы хотите вызвать метод со списком какого-то анонимного типа, вы можете написать:
list.WithEach(x => Console.WriteLine(x.Name), new { Name = "", Value = 10 });
... где финалАргумент будет соответствовать анонимному типу.Это позволит выводить тип T
по последнему параметру вместо второго.Вы можете использовать это для других типов, конечно, но я бы, вероятно, предпочел использовать его для анонимных типов.
Это все довольно ужасный хак, и я не думаю, что на самом деле используйте его, но если вам действительно нужно это для работы с анонимными типами, он справится.