Передача и обработка типов List <>, содержащих объекты одного базового типа - PullRequest
0 голосов
/ 04 июня 2009

Рассмотрим следующие классы:

class TypeA;
class TypeB : TypeA;
class TypeC : TypeA;
class TypeD : TypeA;

и следующие типы List <>:

List<TypeB> listTypeB;
List<TypeC> listTypeC;
List<TypeD> listTypeD;

Теперь у TypeA есть свойство Prop1 типа Object1, и я хочу определить, в каком списке хранится элемент с Prop1 данного значения. Есть ли способ, которым я могу сделать что-то вроде следующего, так что мне нужно написать код поиска только один раз?

bool LocateInAnyList(Object1 findObj)
{
  bool found = false;

  found = ContainsProp1(findObj, listTypeB);
  if(!found)
  {
    found = ContainsProp1(findObj, listTypeC);
  }
  if(!found)
  {
    found = ContainsProp1(findObj, listTypeD);
  }
  return found;
}


bool ContainsProp1(Object1 searchFor, List<TypeA> listToSearch)
{
   bool found = false;

   for(int i = 0; (i < listToSearch.Count) & !found; i++)
   {
      found = listToSearch[i].Prop1 == searchFor;
   }
   return found;
}

Ответы [ 5 ]

5 голосов
/ 04 июня 2009

Да. Вам нужно сделать метод «содержащий» универсальным с ограничением, чтобы вы могли работать только с объектами, которые являются производными от TypeA (и, следовательно, имеют Prop1:)

bool ContainsProp1<T>(Object1 searchFor, List<T> listToSearch) where T : TypeA
{
   bool found = false;

   for(int i = 0; (i < listToSearch.Count) & !found; i++)
   {
      found = listToSearch[i].Prop1 == searchFor;
   }
   return found;
}

Ваш первый метод должен быть скомпилирован как есть.

3 голосов
/ 04 июня 2009

Вы можете использовать общий

bool ContainsProp1<T>(Object1 searchFor, List<T> listToSearch) where T : TypeA
{
   bool found = false;

   for(int i = 0; (i < listToSearch.Count) & !found; i++)
   {
      found = listToSearch[i].Prop1 == searchFor;
   }
   return found;
}

Если вы можете использовать linq, ваш код может быть более понятным.

1 голос
/ 04 июня 2009

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

public bool LocateInAnyList(Object1 obj)
{
    return SearchList(listTypeB, obj) || SearchList(listTypeC, obj) || SearchList(listTypeD, obj);
}

private static bool SearchList<T>(List<T> list, Object1 obj) where T : TypeA
{
    return list.Exists(item => item.Prop1 == obj);
}
0 голосов
/ 04 июня 2009

Да. Во-первых, вы можете сделать метод универсальным, изменив его сигнатуру следующим образом:

bool ContainsProp(Object searchFor, List<T> listToSearch) : where T : TypeA {}

это позволит вам пропустить любой из ваших списков.

Во-вторых, я бы изменил второй параметр, чтобы получить массив списков:

bool ContainsProp<T>(Object searchFor, List<T> [] listsToSearch) where T : TypeA {}

Таким образом, вы можете передать все списки одновременно:

found = ContainsProp(objToSearch, listA, listB, listC);
0 голосов
/ 04 июня 2009

Вы не сможете сделать это таким образом, пока не выйдет C # 4.0 из-за добавленной поддержки дисперсии / ковариации.

Пока вы можете взломать его, позволив пользователю передать IEnumerable и просто зацикливаясь на нем при приведении объекта к TypeA

bool ContainsProp1(Object1 searchFor, IEnumerable listToSearch)
{
   bool found = false;

   foreach(object obj in listToSearch)
   {
      found = ((TypeA)obj).Prop1 == searchFor;
      if (found) break;
   }
   return found;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...