явная ошибка оператора преобразования при преобразовании универсальных списков

Я создаю явный оператор преобразования для преобразования между универсальным списком типов объекта к универсальному списку типов модели. Делает любой знает, почему я получаю следующую ошибку:

Пользовательское преобразование должно преобразовать в или от типа включения

У меня уже есть явный оператор преобразования между 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;
    }

Спасибо за любую справку.

9
задан Marc Gravell 28 December 2009 в 22:40
поделиться

2 ответа

Ошибка "Пользовательское преобразование должно преобразовываться к типу ограждения или из него" точно говорит о том, что оно означает. Если имеется оператор преобразования

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.ConvertAll. Например:

public static class ListExtensions {
    public static List<Model.objA> ConvertToModel(this List<Entity.objA> entities) {
        return entities.ConvertAll(e => (Model.objA)e);
    }
}
23
ответ дан 4 December 2019 в 08:33
поделиться

В принципе, ты не можешь этого сделать. В Вашем операторе тип входа или выхода должен быть тем типом, который декларирует оператор. Одним из вариантов может быть метод расширения, но честно говоря, LINQ Select довольно близок сам по себе, как и List. ConvertAll.

В качестве примера подхода метода расширения:

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().

.
2
ответ дан 4 December 2019 в 08:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: