简体   繁体   English

遍历基类和继承类的所有实例

[英]iterate through all the instances of base class and inherited classes

I have a base class named CollidableObject and a couple of inherited classes named Player , Enemy , InertObject , etc. 我有一个名为CollidableObject的基类和一些名为PlayerEnemyInertObject等的继承类。

I am trying to find an easy way to iterate through all the instances of them, so I initially created a list of the type CollidableObject and put all the instances of the inherited classes in there. 我试图找到一种简单的方法来遍历它们的所有实例,所以我最初创建了一个CollidableObject类型的列表,并将所有继承类的实例放在那里。

The thing is that because of the nature of polymorphism, when I do the following 问题在于,由于多态性的性质,当我做以下事情时

foreach (CollidableObject CollidableObject in collidableObjects)
{
  if (CollidableObject is Player)
  {
    CollidableObject.Draw(spriteBatch, testPlayerTexture); 
  }
  // Then the same prodedure for each type of CollidableObject. 
  // Might change to switch or something.                              
}

The draw method that it calls is the generic Draw method from the CollidbaleObject base, not the overridden/new one from the Player/Enemy/inertObject class. 它调用的draw方法是来自CollidbaleObject库的通用Draw方法,而不是来自Player / Enemy / inertObject类的重写/新方法。

How do I get around this. 我该如何解决这个问题。 Is there a way to iterate through a collection of objects from the same tree but maintaining their inherited type? 有没有办法迭代同一个树中的对象集合,但保持它们的继承类型?

Is there no way to iterate through a collection of objects from the same tree but maintaining their inherited type? 有没有办法迭代同一棵树中的对象集合,但维护它们的继承类型?

Absolutely, there is a way to do that. 当然,有一种方法可以做到这一点。 However, you need to set up your hierarchy in a proper way: 但是,您需要以适当的方式设置层次结构:

  • The Draw method in the CollidableObject needs to be marked virtual CollidableObjectDraw方法需要标记为virtual
  • The Draw method in the Player needs to be marked as an override . PlayerDraw方法需要标记为override

This will ensure that the call from your post would be routed to the Player 's override of the method, not to the method of the base. 这将确保来自您的帖子的调用将被路由到Player的方法覆盖,而不是基础的方法。

On a related note, when you see code that checks the dynamic type of an object with the is operator, as in if (CollidableObject is Player) , you should get strong suspicions that you are doing something incorrectly. 在相关的说明中,当您看到使用is运算符检查对象的动态类型的代码时,如if (CollidableObject is Player) ,您应该强烈怀疑您正在做错误的操作。 For example, you may be missing a double dispatch . 例如,您可能错过了双重调度

If all you need to know is the proper texture for the type, you could put textures in a Dictionary<Type,Texture> textureForType , and pull the right one in your loop using the GetType() of the collidable object. 如果您需要知道的是该类型的正确纹理,您可以将纹理放在Dictionary<Type,Texture> textureForType ,并使用可碰撞对象的GetType()在循环中拉出右边的Dictionary<Type,Texture> textureForType

Have you tried: 你有没有尝试过:

foreach (CollidableObject CollidableObject in collidableObjects)
{
    if (CollidableObject is Player)
    {
        ((Player) CollidableObject).Draw(spriteBatch, testPlayerTexture); 
    }    
    //Then the same prodedure for each type of CollidableObject. Might change to switch or something.                              
}

I would have each class implement a Draw method that is specific to that class. 我希望每个类都实现一个特定于该类的Draw方法。 They would all need the same signature. 他们都需要相同的签名。

Then your foreach doesn't care which class it actually is, and would look like this 那么你的foreach并不关心它实际上是哪一个类,并且看起来像这样

foreach (CollidableObject CollidableObject in collidableObjects)
{
      CollidableObject.Draw(....);                                        
}

This would be the "Object Oriented" way of doing it. 这将是“面向对象”的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM