SomeList <T>: список <T>нельзя преобразовать в список <T>? - PullRequest
0 голосов
/ 03 августа 2011

См. Комментарий в Main (). Почему я не могу выполнить следующее?

   public class SomeList<T> : List<T>
{
    public SomeList(List<T> existing)
    {
        foreach (var item in existing)
            Add(item);
    }

    public override string ToString()
    {
        return "I'm a better list.";
    }
}

internal interface IReadStuff<T>
{
    List<T> ReadStuff();
}

public class ReaderStrategy<Foo> : IReadStuff<Foo>
{
    public List<Foo> ReadStuff()
    {
        return new List<Foo>();
    }
}

public class Foo {}

public class Main
{
    public Main()
    {
        var reader = new ReaderStrategy<Foo>();

        // This works, but type is List<Foo>, not SomeList<Foo>
        List<Foo> aList = reader.ReadStuff();
        // This does not compile, but is what I want to do:
        SomeList<Foo> aBetterList = reader.ReadStuff();
        // This compiles, but always generates null for aBetterList:
        SomeList<Foo> anotherBetterList = reader.ReadStuff() as SomeList<Foo>;
        // This is funky but works:
        SomeList<Foo> works = new SomeList<Foo>(reader.ReadStuff());
    }
}

Мне трудно понять, как использовать дженерики с унаследованными типами. У меня есть потребность в вышесказанном, потому что я хочу расширить функциональность List<T> каким-то особым образом, например, см. SomeList<T> overrides ToString() Однако я хочу сохранить заводскую стратегию, используя .Net generic List<T>. Есть ли способ сделать эту работу?

Редактировать

Я добавил конструктор, который принимает List<T> и добавляет к SomeList<T>. Это не кажется естественным, но работает. Это дорогостоящая операция, особенно если List<T> большой.

Название моего вопроса было не лучшим, к чему я стремился, это пример, показывающий лучший способ сделать это.

Ответы [ 4 ]

3 голосов
/ 03 августа 2011

reader.ReadStuff() возвращает List<Foo> - но вы пытаетесь присвоить его объекту типа SomeList<Foo>, который наследуется от List<Foo>.Это не работает, потому что List<Foo> не является SomeList<Foo> - это наоборот.

Подумайте об этом - законно возвращать объект List<Foo> из ReadStuff() - тогда вы пытаетесь получить доступ к функциональности этого объекта, которая доступна только для SomeList<Foo> - это сломается, и поэтому ООП не позволяет вам это сделать - экземпляры дочернего класса могут использоваться там, где экземплярожидается родительский класс, но вы не можете использовать родительский класс там, где ожидается дочерний класс.

Возвращаясь к названию вашего вопроса: SomeList<T>: List<T> нельзя преобразовать в List<T>?Да, это возможно, но вы пытаетесь привести List<T> к SomeList<T>.

1 голос
/ 03 августа 2011

В вашем примере вы не приводите экземпляр SomeList<Foo> к List<Foo>, вы пытаетесь привести List<Foo> к SomeList<Foo>. Вы переходите от менее конкретного к более конкретному, что не работает. Это должно работать наоборот.

1 голос
/ 03 августа 2011

Все экземпляры SomeList являются экземплярами List.Однако не все экземпляры List являются экземплярами SomeList.Это то, что делает второе задание.reader.ReadStuff () возвращает список, а не SomeList.Надеюсь это поможет.

0 голосов
/ 03 августа 2011

изменить этот код

 SomeList<Foo> aBetterList = reader.ReadStuff() 

 to 
SomeList<Foo> aBetterList = reader.ReadStuff()  as SomeList<Foo>; 

before using 
    if(aBetterList !=null) {}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...