C #: возвращение унаследованного класса из экземпляра его базового класса (общий список) - PullRequest
4 голосов
/ 16 сентября 2010

Это, вероятно, я просто вспоминаю вещи задом наперед, но я хотел бы узнать больше о том, что я делаю неправильно ...

Я объявил класс не более чем прямым наследованиемиз общего списка (сделано для упрощения именования), что-то вроде этого:

public class FooList : List<Foo> {}

теперь в другом методе, полностью отделенном от этого класса, я пытаюсь вернуть экземпляр этого класса, однако я хочу отфильтроватькласс основан на критерии, поэтому я использую лямбда-выражение:

var list = new FooList(); // imagine this fills it with different items
var filtered = list.FindAll(c => c.Something == "filter criteria");

теперь в соответствии с методом FindAll, это ДОЛЖНО вернуть List [Foo].Однако я хочу вернуть этот объект как FooList, а не как List [Foo].Нужно ли создавать новый экземпляр FooList и копировать элементы из списка [Foo]?

Если да, то почему?почему я не могу преобразовать List в FooList напрямую, поскольку это один и тот же объект?

Если это МОЖЕТ быть сделано, как мне это сделать?

большое спасибо!

Ответы [ 3 ]

8 голосов
/ 16 сентября 2010

Ваша проблема в том, что вы используете неправильный инструмент для работы. Наследование не является механизмом для упрощения именования ; Наследование - это механизм, в первую очередь предназначенный для (1) моделирования «своего рода» отношений между классами объектов бизнес-области и (2) обеспечения совместного использования и специализации деталей реализации среди связанных типов.

Если вы хотите упростить наименование, тогда правильный инструмент для работы - поставить

using FooList = System.Collections.Generic.List<Foo>;

вверху каждого файла.

6 голосов
/ 16 сентября 2010

Они не одно и то же. FooList - это List<foo>, но List<foo>, которое возвращается функцией FindAll(), унаследованной от List<foo>, равно , а не a FooList. Вам нужно будет построить новый FooList.

Вы можете сделать что-то вроде создания конструктора для FooList, который принимает объект IEnumerable<foo>, например:

class FooList : List<foo>
{
   public FooList(IEnumerable<foo> l)
        : base(l)
   {  }
}

Или вы также можете сделать что-то вроде этого:

 var list = new FooList();
 var filtered = list.FindAll(c => c.Something == "filter criteria");
 var newList = new FooList();
 newList.AddRange(filtered);
 return newList;

Однако, как уже упоминалось в некоторых других ответах, если вы не добавляете какие-либо функции, вам просто нужно создать псевдоним с ключевым словом using.

1 голос
/ 16 сентября 2010

Не объявляйте новый класс FooList. Просто используйте псевдоним. В верхней части исходного файла напишите:

using FooList = System.Collections.Generic.List<Foo>;

Теперь вы можете написать FooList везде, и он будет считаться абсолютно идентичным List<Foo>.

...