Приведение списка производного класса к списку базового класса, все еще возвращающего объекты производного класса

У меня есть следующий код:

public class BaseClass
{
    public string A { get; set; }
}

public class DerivedClass : BaseClass
{
    public string B { get; set; }
}


List<DerivedClass> _derivedClass = new List<DerivedClass>() 
                                       { 
                                           new DerivedClass() 
                                             { A = "test1",
                                               B = "test2"
                                             }
                                       }; 

List<BaseClass> _baseClass = _derivedClass.Cast<BaseClass>.ToList();

Код компилируется без ошибок, однако я ожидал, что _baseClass будет содержать только свойство A (объект типа BaseClass), но он возвращает свойства A и B (объекты типа DerivedClass). Что мне не хватает и как правильно преобразовать список производного класса в список его базового класса?

Спасибо.


person Sam Dingo    schedule 11.02.2013    source источник
comment
Почему вас волнует, что это действительно DerivedClass за кулисами?   -  person D Stanley    schedule 11.02.2013
comment
Как вы получаете доступ к этим свойствам? Мне кажется нормально...   -  person Dave Bish    schedule 11.02.2013
comment
Привет, ребята, смотрите мой ответ @ReedCopsey ниже. Спасибо.   -  person Sam Dingo    schedule 11.02.2013


Ответы (1)


Что мне не хватает и как правильно преобразовать список производного класса в список его базового класса?

Список по-прежнему содержит экземпляры DerivedClass, но они используются как ссылки на BaseClass.

Однако любой потребитель этого API не будет знать об этом, поэтому он увидит это как BaseClass элементов.

Это распространенный и, как правило, правильный подход. Если вам нужно на самом деле преобразовать экземпляры в экземпляры BaseClass (что, скорее всего, не обязательно), вам нужно будет фактически создать новые экземпляры BaseClass из DerivedClass членов, т.е.:

List<BaseClass> _baseClass = _derivedClass.Select(dc => new BaseClass {A = dc.A}).ToList();

Обычно в этом нет необходимости, и ваш текущий подход, скорее всего, подойдет. принцип замены Лисков гласит, что любой DerivedClass должен использоваться в любой ситуации как BaseClass, что означает просто возврат списка по мере того, как вы сделал должно быть хорошо.

person Reed Copsey    schedule 11.02.2013
comment
Спасибо за подробный ответ. Это имеет смысл, и ваше решение сработало. Короче говоря, я создаю слой API с использованием веб-API MVC 4, и сериализатор включает свойства производного класса, а не только базового класса. Размер полезной нагрузки был слишком большим, и я пытался уменьшить объем данных, отправляемых обратно клиенту. - person Sam Dingo; 11.02.2013