Как установить базовый член универсального списка <T>, используя производный специфический список <TUser> - PullRequest
0 голосов
/ 16 марта 2012

У меня ошибка компилятора при попытке установить элемент базового класса универсальной коллекции в этом производном классе.

error CS0029: Cannot implicitly convert type 'System.Collections.Generic.List<IntSegment>' to 'System.Collections.Generic.List<T>'

Вот схема моей общей коллекции

public class Path<T> : IEnumerable<T> where T : Segment
{
    private List<T> segments = new List<T>();

    public List<T> Segments
    {
        set { segments = value; }
        get { return this.segments; }
    }

    public Path()
    {
        this.Segments = new List<T>();
    }

    public Path(List<T> s)
    {
        this.Segments = s;
    }
}

Затем определяется производный универсальный класс этой коллекции для производного класса IntSegment of Segment (для которого определена базовая коллекция)

public class IntersectionClosedPath<T> : Path<T>, IEnumerable<T> where T : IntSegment
{
    public IntersectionClosedPath(List<IntSegment> inEdges)
        : base()
    {
        Segments = inEdges;
    }
}

Я не могу понять, почему это назначение не разрешено,(Мне не нужно делать глубокую копию входящего списка).

Ответы [ 3 ]

5 голосов
/ 16 марта 2012

Измените List<IntSegment> inEdges на List<T> inEdges, и это будет работать.Проблема в том, что Segments известен как List<T>, where T : IntSegment, а inEdges - это List<IntSegment>.(По причинам, по которым я не буду вдаваться, если вы не спросите, такое назначение не разрешено. Посмотрите дисперсию / ковариацию / контравариантность, если вам интересно.)

4 голосов
/ 16 марта 2012

Классическая проблема.List<Derived> нельзя неявно преобразовать в List<Base>.

. Вы можете разыграть элементы в List<Derived> и создать List<Base> следующим образом:

listOfBase = listOfDerived.Cast<Base>().ToList();
3 голосов
/ 16 марта 2012

A List<T> не эквивалентно List<TBase>, где T : TBase.

Почему?Поскольку List<T> не не наследует от List<TBase>, связаны только параметры общего типа.

Вместо этого вы можете сделать это в конструкторе:

Segments = inEdges.Cast<Segment>().ToList()

Я бы также изменил параметр конструктора на IEnumerable<IntSegment>

Точно так же, возможно, @Tim S. имеет лучшее решение на основе того, чего вы хотите достичь.Лично я считаю, что он, вероятно, прибил это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...