Вопрос

Как я могу заставить следующий код работать?Я не думаю, что я вполне разбираюсь в C # generics.Возможно, кто-нибудь сможет указать мне правильное направление.

    public abstract class A
    {
    }

    public class B : A
    {
    }

    public class C : A
    {
    }

    public static List<C> GetCList()
    {
        return new List<C>();
    }

    static void Main(string[] args)
    {
        List<A> listA = new List<A>();

        listA.Add(new B());
        listA.Add(new C());

        // Compiler cannot implicitly convert
        List<A> listB = new List<B>();

        // Compiler cannot implicitly convert
        List<A> listC = GetCList();

        // However, copying each element is fine
        // It has something to do with generics (I think)
        List<B> listD = new List<B>();
        foreach (B b in listD)
        {
            listB.Add(b);
        }
    }

Вероятно, это простой ответ.

Обновить:Во-первых, это невозможно в C # 3.0, но будет возможно в C # 4.0.

Чтобы запустить его на C # 3.0, который является всего лишь обходным путем до версии 4.0, используйте следующее:

        // Compiler is happy
        List<A> listB = new List<B>().OfType<A>().ToList();

        // Compiler is happy
        List<A> listC = GetCList().OfType<A>().ToList();
Это было полезно?

Решение

ты всегда мог бы это сделать

List<A> testme = new List<B>().OfType<A>().ToList();

Как отметил "Боян Резник", вы тоже могли бы это сделать...

List<A> testme = new List<B>().Cast<A>().ToList();

Разница, которую следует отметить, заключается в том, что приведение<T>() завершится ошибкой, если один или несколько типов не совпадают.Где OfType<T>() вернет IEnumerable<T> содержащий только объекты, которые являются конвертируемыми

Другие советы

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

List<Giraffe> giraffes = new List<Giraffe>();
List<Animal> animals = giraffes; // suppose this were legal.
// animals is now a reference to a list of giraffes, 
// but the type system doesn't know that.
// You can put a turtle into a list of animals...
animals.Add(new Turtle());  

И, эй, вы только что поместили черепаху в список жирафов, и теперь целостность системы типов была нарушена.Вот почему это незаконно.

Ключевым моментом здесь является то, что "животные" и "жирафы" относятся к ОДНОМУ и тому ЖЕ ОБЪЕКТУ, и этот объект представляет собой список жирафов.Но список жирафов не может сделать столько, сколько может сделать список животных;в частности, в нем не может содержаться черепаха.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top