【问题标题】:Looping through a List of objects with the same base class and extracting a certain class?循环遍历具有相同基类的对象列表并提取某个类?
【发布时间】:2013-05-04 11:55:33
【问题描述】:

例如,我有一个基类Entity,然后是从它派生的两个子类LightEntityPlayerEntity

然后我有一个List<Entity> Entities,其中包含LightEntitys 和PlayerEntitys。

我希望从Entities获得所有LightEntitys。

我试过了:

List<LightEntity> lights = new List<LightEntity>();
foreach (Entity ent in Entities)
{
    if(ent is LightEntity)
    {
        lights.Add(ent);
    }
}

但它不喜欢这样,因为编译器似乎仍然认为它可能会尝试将 Entity 添加到 LightEntity 列表中。

我尝试将ent 转换为LightEntity,但编译器说它没有将Entity 转换为LightEntity 的方法。

【问题讨论】:

  • 我想告诉你原因。在 c# 中,不允许隐式向下转换。这意味着您必须继续进行显式转换,这会告诉 CLR 在我的情况下进行这种向下转换是安全的。

标签: c# class object inheritance


【解决方案1】:

您可以使用OfType 按类型过滤实体:

List<LightEntity> lights = new List<LightEntity>();
lights.AddRange(entities.OfType<LightEntity>());

或者更简单:

List<LightEntity> lights = entities.OfType<LightEntity>().ToList();

进一步阅读

【讨论】:

  • 同意 Linq 让这个非常漂亮:)
  • 我以前没有听说过 Linq 是不是很糟糕?我只在业余时间从事 C# 工作。
  • 严格来说这不是 Linq 而是 IEnumerable 扩展
  • 谢谢,该链接无效,但我通过谷歌搜索您发布的标题找到了它。看起来很有用,以后肯定会用到。
  • @MatthewMcGovern 很抱歉。为了完整起见,我添加了答案的链接。
【解决方案2】:

List(Of T) 扩展解决方案已经写好了,让我展示一下这种老式的方式

List<LightEntity> lights = new List<LightEntity>();
foreach (Entity ent in Entities)
{
    LightEntity le = ent as LightEntity
    if(le != null)
    {
        lights.Add(le);
    }
}

【讨论】:

    【解决方案3】:

    嗯,首先。我不知道您为什么要这样做,但我很确定这不是解决您的问题的最佳方法。可能您的派生类不应该具有相同的基类或类似的东西。如果你需要帮助,你应该给我们更大的图景。

    正如已经发布的那样,投射是解决您问题的方法。

    Lights.Add((LightEntity)ent);
    

    【讨论】:

    • 是的,我开始怀疑它们是否真的需要相同的基类,尽管它们确实共享许多通用代码(基本更新函数、基本绘制函数、许多成员变量),并且将它们存储在同一个列表中是因为实体可以有许多子实体,我需要一种方法将它们全部保存在一个地方,以便存储关系并从 Parent->Child 更新它们
    【解决方案4】:

    你可以用 linq 做到这一点......

     var lights = Entities.Where(e => e is LightEntity)
                          .Select(e => (LightEntity)e)
                          .ToList();
    

    【讨论】:

      【解决方案5】:

      只需将 ent 转换为 (LightEntity) 所以

      Lights.Add((LightEntity)ent);
      

      【讨论】:

      • InvalidCastException was unhandled - Unable to cast object of type PlayerEntity to type LightEntity
      • @MatthewMcGovern - 将该行放在 if 语句中。
      • 这很奇怪,因为您正在检查 ent 是否为 LightEntity。 PlayerEntity 是继承自 LightEntity 还是什么?
      • @P.Brian.Mackey Derp... 我试过这种方式,但我没有先检查类型。凯尔,是的,它工作得很好,我是愚蠢的!
      • @MatthewMcGovern 不用担心。
      猜你喜欢
      • 1970-01-01
      • 2018-08-11
      • 2011-06-11
      • 1970-01-01
      • 1970-01-01
      • 2019-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多