Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在列表中获取特定的派生对象<;T>;?_C#_.net_List_Collections_Filter - Fatal编程技术网

C# 如何在列表中获取特定的派生对象<;T>;?

C# 如何在列表中获取特定的派生对象<;T>;?,c#,.net,list,collections,filter,C#,.net,List,Collections,Filter,假设我有一个水果的通用列表(list fruits=new list())。然后,我添加了两个对象(都是从水果)-香蕉,苹果,橙色,但在派生对象上具有不同的属性(例如香蕉.IsYellow) 但在执行时,这当然无效,因为Apple和Orange对象上没有IsYellow属性 如何从列表中仅获取香蕉、苹果、橙子等?foreach(水果中的香蕉b.OfType()) 你可以这样做 foreach(Fruit fruit in fruits) { Banana b = fruit as Bana

假设我有一个水果的通用列表(
list fruits=new list()
)。然后,我添加了两个对象(都是从
水果
)-
香蕉
苹果
橙色
,但在派生对象上具有不同的属性(例如
香蕉.IsYellow

但在执行时,这当然无效,因为Apple和Orange对象上没有IsYellow属性

如何从
列表中仅获取香蕉、苹果、橙子等?

foreach(水果中的香蕉b.OfType())
你可以这样做

foreach(Fruit fruit in fruits)
{
   Banana b = fruit as Banana;
   if(b != null)
   {
      Console.Write(b.IsYellow);
   }
}

就我个人而言,我觉得这种方法更具可读性:

foreach(Fruit fruit in fruits)
{
   if (fruit is Banana)
   {
      Banana b = fruit as Banana;
      Console.Write(b.IsYellow);
   }
   else if (fruit is Apple)
   {
      // ...
   }
}
步骤1: 首先,你们应该从水果清单中列出子清单。要创建子列表,请使用Generic的
FindAll()
谓词
函数

步骤2: 稍后,您可以在子集中迭代,该子集中只包含“Banana”

这是密码

步骤1:

List<Fruit> fruits = new List<Fruit>();
Banana banana1 = new Banana();
Banana banana2 = new Banana();
Apple apple1 = new Apple();
Orange orange1 = new Orange();

fruits.Add(banana1);
fruits.Add(banana2);
fruits.Add(apple1);
fruits.Add(orange1);

//Extract Banana from fruit list
List<Fruit> bananaComb = fruits.FindAll(IsBanana);

//Now iterate without worring about which fruit it is
foreach (Fruit fruit in bananaComb)
{
    Console.WriteLine(((Banana)fruit).IsYellow);
}

不过,添加另一种语法可能是最好的

foreach (Banana b in fruits.Where(x => x is Banana))

哇,我不知道那个。美好的是的,这是可行的,但是我使用的是根UnitOfWork/Repository上下文,所以“水果列表”将包含很多对象,在该上下文中制作一个副本不是一个好主意。别担心。子列表并不是一个真正的副本,相反,它只包含指向主列表上“香蕉”的指针。我已经检查了我的示例代码,以了解有关List.FindAll()的更多信息。但是,您将收到一个轻微的性能影响和一个代码分析警告,告诉您不要不必要地强制转换,因为您实际上要执行两次。啊,循环if-then-else反模式[与循环案例语句非常相似]。我的眼睛在流血。不是因为你的例子,而是这些东西发展成了不可维护的癌症。上面的评论是有意义的,但是在Ian的例子中有没有更好的方法避免空检查呢。这是让我眼睛流血的部分。我们在谈论水果,而IsYellow是一个对象状态(颜色或颜色)的派生属性。如果他们都有一种颜色(他们可能应该这样做),然后检查它。通常使用这种模式而不是使用继承,并不是所有这种情况都是错误的,但在相当长的时间内(大多数情况下?)似乎确实是错误的。参见Fowler的重构。有人知道如何在C++中实现吗?我也陷入了这种困境,但是我正在用C++编写我的代码!
foreach(Fruit fruit in fruits)
{
   if (fruit is Banana)
   {
      Banana b = fruit as Banana;
      Console.Write(b.IsYellow);
   }
   else if (fruit is Apple)
   {
      // ...
   }
}
List<Fruit> fruits = new List<Fruit>();
Banana banana1 = new Banana();
Banana banana2 = new Banana();
Apple apple1 = new Apple();
Orange orange1 = new Orange();

fruits.Add(banana1);
fruits.Add(banana2);
fruits.Add(apple1);
fruits.Add(orange1);

//Extract Banana from fruit list
List<Fruit> bananaComb = fruits.FindAll(IsBanana);

//Now iterate without worring about which fruit it is
foreach (Fruit fruit in bananaComb)
{
    Console.WriteLine(((Banana)fruit).IsYellow);
}
//A Predicate function to determine whether its a Banana
static protected bool IsBanana(Fruit aFruit)
{
    return aFruit.GetType().Name == "Banana" ? true : false;
}
foreach (Banana b in fruits.Where(x => x is Banana))