【问题标题】:Removing special type from list that contains multiple types C#从包含多种类型 C# 的列表中删除特殊类型
【发布时间】:2017-06-16 02:21:45
【问题描述】:

我遇到的问题是我想从包含 2 种不同类型的列表中删除某个项目。无论我尝试什么,我都会得到错误并且我可以使用类型,如果我创建该类的新实例,它不会删除旧的。我真的被困在这里,我不知道该怎么办。

private List<Toys> toys = new List<Toys>();
toys.Add(new Ball("red"));
toys.Add(new MouseToy("gray"));

public abstract class Toys {}    
public class Ball : Toys {}
public class MouseToy : Toys {}

//how do i remove only one of the types?
//beacuse this does not work witch is one of many things i tried
    foreach(var toy in toys){
       if (toy.GetType == Ball){
          toys.Remove(toy)
       }
     }

这几乎就是我用于列表的代码。

【问题讨论】:

    标签: c# .net list subclass base-class


    【解决方案1】:

    你可以这样做:

    toys = toys.Where(toy=>!(toy is Ball)).ToList();
    

    正如在 cmets 中提到的@Sefe(谢谢):你可以使用它来做更简单和更好的

    List<MouseToy> mouseToys =  toys.OfType<MouseToy>().ToList();
    

    如果您认为您的新收藏将是 List&lt;MouseToy&gt; 而不是 List&lt;Toys&gt; 对您来说没问题。如果您将获得第三类 CatToy 并且您仍然想要获得所有物品,但不是 Ball 类的,那将无法正常工作

    【讨论】:

    • 就这么简单吗?我的意思是我不认为我真的了解它的作用。玩具有什么价值“典型”“东西”?
    • 哦,等一下,我想我明白了,我从列表中删除了球对象,然后再次将其添加到仅包含其余部分的列表中。
    • @JohannesBjärehall 是的,您创建了一个新列表,其中只有那些不是 Ball 的对象。
    • 为什么要使用Where 而不是OfType?你当然可以从窗户进屋,但为什么不使用门呢?
    • @Sefe 真正的答案是:我已经忘记了它并采取了最明显和最简单(对我来说)的答案,确定你是对的,如果我们只想拥有 MouseToys 更好的是使用 OfType . OP想要没有MouseToys而是“没有Balls”,如果有第三类CatToy就不一样了。我会更新答案,因为您的观点是正确的,对于这种情况,使用 OfType 更好。并且 OfType 将返回 List 而不是玩具列表
    【解决方案2】:

    您的解决方案有两个问题:

    1. 您正在使用foreach 修改您正在迭代的列表。这将导致InvalidOperationException
    2. .GetType == Ball 不能这样工作。请改用is

    试试这个:

    foreach(var toy in toys.ToArray()){
       if (toy is Ball){
          toys.Remove(toy);
       }
    }
    

    您也可以使用 LINQ:

    foreach(var toy in toys.OfType<Ball>().ToArray()){
      toys.Remove(toy);
    }
    

    【讨论】:

    • 哥们,我确实学到了一些东西,当我现在看到它时真的很容易哈哈,反正坦克!
    【解决方案3】:

    在迭代同一列表时,您无法从列表中删除项目。您可以使用反向 for 循环(即循环降序):

    for (int i = toys.Length - 1; i >= 0; i--)
    {
        if (toys[i] is Ball)
        {
            toys.RemoveAt(i);
        }
    }
    

    ...或者您可以使用System.Linq 命名空间中定义的方法之一。 Maksim Simkin 展示了如何使用Where 方法;你也可以使用OfTypeExcept 方法:

    toys = toys.Except(toys.OfType<Ball>())
               .ToList();
    

    【讨论】:

    • 感谢您的帮助,当我看到您的代码时,它似乎很明显。
    猜你喜欢
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 2019-10-03
    • 1970-01-01
    相关资源
    最近更新 更多