SelectMany не может быть выведен из использования
Я получаю следующую ошибку при попытке скомпилировать свой код:
Аргументы типа для метода "System.Linq.Enumerable.SelectMany(System.Collections.Generic.IEnumerable, System.Func > )" не может быть выведено из использования. Попробуйте указать аргументы типа в явном виде.
List<RowEntry> entries = ...
List<RowArgument> arguments = ...
var argumentsVal = entries.SelectMany((RowEntry entry) =>
(IEnumerable<RowArgumentVal>)arguments.SelectMany((RowArgument arg) =>
new RowArgumentVal()
{
Action = "X"
, EntryID = entry.ID
, ArgID = arg.ID
, Val_BIT = true
, Val_DATE = new DateTime(2014, 01, 04)
, Val_DATETIME = new DateTime(2014, 01, 04)
, Val_DECIMAL = 4.6M
, Val_INT = 88
, Val_TIME = new TimeSpan(6, 0, 0)
}
).Cast<RowArgumentVal>()).Cast<RowArgumentVal>().ToList();
Я не понимаю, как я могу "напечатать" это еще дальше...
Ответы
Ответ 1
Проблема в том, что внутренний SelectMany
там не применим, и вы, вероятно, имели в виду Select
.
var argumentsVal = entries.SelectMany(entry =>
arguments.Select(arg => new RowArgumentVal())).ToList();
Каждый entry
будет отображаться в IEnumerable<RowArgumentVal>
в соответствии с arguments
.
Представьте, что внешний SelectMany
был простым Select
, и он генерировал бы List<IEnumerable<RowArgumentVal>>
. Но поскольку это SelectMany
, он "сгладит" результат в простой List<RowArgumentVal>
.
Метод SelectMany
ожидает сопоставления с IEnumerable<T>
- not T
. Ваш исходный код будет действителен, если только RowArgumentVal
реализовал интерфейс IEnumerable<T>
, который, я полагаю, не тот.
Ответ 2
Это кажется декартовым продуктом из обоих списков, поскольку между ними нет никакой связи. Вы можете присоединиться к ним, но это не совсем понятно, как это сделать.
Вот более читаемый и компилирующий способ создания декартова продукта:
var query = from entry in entries
from argument in arguments
select new RowArgumentVal
{
Action = "X", EntryID = entry.ID, ArgID = argument.ID, // ...
};
List<RowArgumentVal> argumentsVal = query.ToList();
Ответ 3
Если вы хотите, чтобы декартовой продукт попытался сделать следующее
var argumentsVal = from e in entries
from a in arguments
select new RowArgumentVal(...)
Ответ 4
В стороне, "дальнейшая набрав", которую вы могли бы сделать, было бы дать аргументы типа вызовам общего метода. В частности, если вы изменили второй SelectMany
на SelectMany<RowArgument, RowArgumentVal>
, у вас были бы ошибки
Невозможно неявно преобразовать тип RowArgumentVal
в System.Collections.Generic.IEnumerable<RowArgumentVal>
. Явное преобразование существует (вы пропускаете листинг?)
Невозможно преобразовать лямбда-выражение для делегирования типа System.Func<RowArgument,int,System.Collections.Generic.IEnumerable<RowArgumentVal>>
, потому что некоторые возвращаемые типы в блоке неявно конвертируются в тип возвращаемого делегата
который, возможно, привел бы вас к другим ответам здесь, - что вы пытались вызвать метод, ожидающий последовательности, но вы давали ему один объект.
(Или, пытаясь решить, какие аргументы типа добавить, вы бы поняли, что было раньше.)