Самое простое решение - просто использовать оператор Cast<>
LINQ:
public IEnumerable<IMyType> All() {
var query = _connection.Query("SELECT * FROM [table]");
return query.Select(o => _myTypeFactory.Create(o))
.Cast<IMyType>();
}
Кроме того, вы можете разыграть каждый элемент:
public IEnumerable<IMyType> All() {
var query = _connection.Query("SELECT * FROM [table]");
return query.Select(o => (IMyType) _myTypeFactory.Create(o));
}
В настоящее время это не работает, потому что просто невозможно неявное преобразование между IEnumerable<dynamic>
и IEnumerable<IMyType>
. IEnumerable<dynamic>
может быть реализовано любым количеством способов, и учитывая, что каждый элемент будет сгенерирован динамически нет оснований предполагать, что значение результата будет реализовано IEnumerable<IMyType>
.
Я согласен, что выглядит как будто вторая форма фактически ничего не добавляет, но компилятор не проверяет все возможные возвращаемые типы _myTypeFactory.Create(o)
- он обрабатывает это целое выражение как динамическое значение, т.е. выражение имеет тип dynamic
. Поэтому результат Select
все еще имеет тип IEnumerable<dynamic>
.
Другой вариант - указать аргумент универсального типа для Select
.
public IEnumerable<IMyType> All() {
var query = _connection.Query("SELECT * FROM [table]");
return query.Select<IMyType>(o => _myTypeFactory.Create(o));
}
Это пытается заставить лямбда-выражение к Func<dynamic, IMyType>
- я верю , что будет работать ...
РЕДАКТИРОВАТЬ: Как отмечено в комментариях, принудительное разрешение вызова метода во время компиляции также исправит это. В основном это зависит от того, что вы считаете наиболее читабельным.