Я создаю явный оператор преобразования для преобразования между универсальным списком типов объекта к универсальному списку типов модели. Делает любой знает, почему я получаю следующую ошибку:
Пользовательское преобразование должно преобразовать в или от типа включения
У меня уже есть явный оператор преобразования между Entity.objA и Model.objA, который хорошо работает. Проблема возникает при попытке преобразовать универсальный список. Это даже возможно?
Вот мой код:
public static explicit operator List<Model.objA>(List<Entity.objA> entities)
{
List<Model.objA> objs= new List<Model.objA>();
foreach (Entity.objA entity in entities)
{
objs.Add((Model.objA)entity);
}
return claims;
}
Спасибо за любую справку.
Ошибка "Пользовательское преобразование должно преобразовываться к типу ограждения или из него" точно говорит о том, что оно означает. Если имеется оператор преобразования
class MyClass {
public static explicit operator xxx(string s) { // details }
public static implicit operator string(xxx x) { // details }
}
, то xxx
должно быть MyClass
. Это означает, что "приведение должно приводить к или от типа заключения". Типом ограждения здесь является MyClass
.
Соответствующий раздел спецификации ECMA334 C# составляет 17.9.4:
Оператор преобразования преобразует из типа источника, указываемого типом параметра оператора преобразования, в тип цели, указываемый типом возврата оператора преобразования. Класс или структура могут объявить преобразование из исходного типа S в целевой тип T только в том случае, если все нижеследующее является истинным, где S0 и T0 - это типы, являющиеся результатом удаления модификаторов трейлинга, если таковые имеются, из S и T:
S0 и T0 - это разные типы.
S0 или T0 - это тип класса или структуры, в котором происходит объявление оператора.
Ни S0, ни T0 не являются типом интерфейса.
Исключая пользовательские приведения, преобразование из S в T или из T в S не существует.
Итак, вот ваш код:
public static explicit operator List<Model.objA>(List<Entity.objA> entities) {
List<Model.objA> objs= new List<Model.objA>();
foreach (Entity.objA entity in entities) {
objs.Add((Model.objA)entity);
}
return claims;
}
Дело в том, что для того, чтобы это было определено как оператор преобразования, оно должно находиться в List
или List
классов, но, конечно, вы не можете этого сделать, так как у вас нет доступа к изменению этих типов.
Вы можете использовать Enumerable.Select
для проектирования на другой тип, или List
. Например:
public static class ListExtensions {
public static List<Model.objA> ConvertToModel(this List<Entity.objA> entities) {
return entities.ConvertAll(e => (Model.objA)e);
}
}
В принципе, ты не можешь этого сделать. В Вашем операторе тип входа или выхода должен быть тем типом, который декларирует оператор. Одним из вариантов может быть метод расширения, но честно говоря, LINQ Select
довольно близок сам по себе, как и List
.
В качестве примера подхода метода расширения:
public static class MyListUtils {
public static List<Model.objA> ToModel(this List<Entity.objA> entities)
{
return entities.ConvertAll(entity => (Model.objA)entity);
}
}
или более общего с LINQ Select
:
public static class MyListUtils {
public static IEnumerable<Model.objA> ToModel(
this IEnumerable<Entity.objA> entities)
{
return entities.Select(entity => (Model.objA)entity);
}
}
и просто используйте someList.ToModel()
.