传递和处理List<>包含相同基类型的对象的类型

时间:2009-06-04 13:52:11

标签: c# inheritance collections

考虑以下课程:

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

以及以下列表<>类型:

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

现在TypeA有一个Object1类型的属性Prop1,我想找到哪个列表中存储了一个给定值为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 个答案:

答案 0 :(得分:5)

是。您需要使用约束使“包含”方法具有通用性,以便您只能对源自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;
}

然后你的第一个方法应该按原样编译。

答案 1 :(得分:3)

您可以使用通用

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,你的代码可以比那更清楚。

答案 2 :(得分:1)

你可以做这样的事情(使用lambdas&amp; generics&amp; good things):

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);
}

答案 3 :(得分:-1)

在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;
}

答案 4 :(得分:-1)

是。首先,您可以通过更改其签名来使方法具有通用性:

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);