2013-04-21 4 views
1

У меня есть class X, который представляет элемент. Классы A, B, C и D являются подклассами этого и добавляют дополнительное поведение к элементу.Метод возвращает список суперклассов вместо подклассов

У меня есть enum ElementType со значениями TypeA, TypeB, TypeC и TypeD.

В моем текущем сценарии есть class Y, который содержит коллекцию типа X и имеет method GetElementsByType(ElementType type).

Когда этот метод вызывается, я хочу вернуть список всех элементов в списке с элементами в соответствии с типом.

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

public List<X> GetElementsByType(ElementType type) { 
     switch (type) { 
      case ElementType.TypeA: 
       return Elementen.OfType<A>().ToList(); 
      case ElementType.TypeB: 
       return Elementen.OfType<B>().ToList(); 
      case ElementType.TypeC: 
       return Elementen.OfType<C>().ToList(); 
      case ElementType.TypeD: 
       return Elementen.OfType<D>().ToList(); 
      default: 
       throw new ArgumentException(); 
     } 
    } 

В моей 2-ой попытки я пытался избежать этого преобразования, делая каждый подкласс реализовать общий интерфейс, который должен избежать ошибок преобразования.

Я закончил с этим:

public interface IElement { 
} 

A : X, IElement 
B : X, IElement 
C : X, IElement 
D : X, IElement 


public List<IElement> GetElementsByType(ElementType type) { 
      switch (type) { 
       case ElementType.TypeA: 
        return new List<IElement>(Elementen.OfType<A>().ToList()); 
       case ElementType.TypeB: 
        return new List<IElement>(Elementen.OfType<B>().ToList()); 
       case ElementType.TypeC: 
        return new List<IElement>(Elementen.OfType<C>().ToList()); 
       case ElementType.TypeD: 
        return new List<IElement>(Elementen.OfType<D>().ToList()); 
       default: 
        throw new ArgumentException(); 
      } 
     } 

Однако, когда я называю этот метод из где-то, например,

var result = obj.GetElementsByType(ElementType.TypeA).FirstOfDefault(a => a.PropX == variable)

Я заметил, что лямбда-выражение не может получить какой-либо из свойства из Element, но вместо этого я оставил все, что определено внутри IElement (ничего).

Как исправить это, чтобы я мог вызвать один метод, добавить параметр enum в качестве параметра и вернуть List подклассов из одного Collection, определенного как суперкласс?

+0

Зачем вам нужен 'ElementType' перечисления на всех? Поскольку тип элементов списка должен быть указан, не будет 'List myList = GetElementsByType ();' будет достаточным? Другими словами, вы не могли бы сделать тип типичным параметром типа вместо параметра функции? – dasblinkenlight

+0

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

ответ

4

Вы могли бы сделать это немного проще:

public List<T> GetElementsByType<T>() where T : X 
{ 
     return Elementen.OfType<T>().ToList(); 
} 
+0

Я еще не коснулся этой ('где T: X') части синтаксиса C#, спасибо, что указал на нее. Как мне обратиться к этому методу с параметром? Я не вижу, где определяется тип, который должен быть запрошен. –

+0

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

+0

@ Kenneth Теперь это лучше :) Предполагая, что OP в порядке с этим решением (т. Е. Параметр типового типа, а не его параметр «ElementType»), это сделает трюк. – dasblinkenlight

Смежные вопросы