2010-09-15 2 views
4

Возможно, я просто помню вещи полностью назад, но я хотел бы узнать больше о том, что я делаю неправильно ...C#: возвращение унаследованного класса из экземпляра его базового класса (общий список)

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

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, это СЛЕДУЕТ вернуть список [Foo]. Однако я хочу вернуть этот объект как FooList, а не List [Foo]. Должен ли я создать новый экземпляр FooList и скопировать элементы из списка [Foo]?

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

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

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

+0

Должно ли мы воспринимать это '{}' как определение FooList буквально? Или вы хотите добавить некоторых участников? –

ответ

6

Это не одно и то же. FooList является List<foo> но List<foo>, который возвращается функцией FindAll() унаследованного от List<foo>, является не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.

+0

вот о чем я подумал, но мне кажется, что это ДОЛЖНО работать, но я думаю, что понимаю, почему это не так. Я знал, что у меня есть это в обратном направлении. есть ли способ инициализировать FooList из списка [Foo], или я собираюсь вместо этого добавить каждый отдельно? Кстати, СПАСИБО! – SelAromDotNet

+2

С положительной стороны Список имеет перегрузку конструктора, которая принимает аргумент IEnumerable , поэтому создание нового FooList и копирование значений должно быть простым. – PhilB

+0

@PhilB +1 За избиение меня, пока я отсутствовал, кодирование :) – linuxuser27

8

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

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

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

в верхней части каждого файла.

+0

интересно, я никогда не слышал об этом раньше, я загляну в него! первоначально предполагалось, что к этому добавили функциональность, но мы так и не добрались туда. Я обязательно буду помнить это о будущем, спасибо! – SelAromDotNet

+0

+1 Все. Для OP нет необходимости создавать класс ListFoo, унаследованный от «List », чтобы сделать код короче. 'using' разрешает проблему с корнем. –

1

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

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

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