C#从基类列表

时间:2017-01-09 13:47:02

标签: c# xna-4.0

首先,我创建基类并继承类

public class Entity
{
   public int EntityID;
   public EntityType type = EntityType.NONE;
}

public class EntityObject : Entity
{
   public Vector2 position;
   public EntityObject()
   {
      position = Vector2.Zero;
      type = EntityType.OBJECT;
   }
}

然后我创建基类列表来存储所有继承的类

List<Entity> entityList = new List<Entity>();
entityList.Add(new EntityObject());

稍后,我尝试访问列表

中的继承类的成员
for(int i = 0; i < entityList.Count; i++)
    if(entityList[i].type == EntityType.OBJECT)
        entityList[i].position = Vector2.One;

是的,我收到一个错误:'实体'不包含'position'的定义,也没有扩展方法'position'接受类型'Entity'的第一个参数可以找到(你是否错过了使用指令或者装配参考?)

是否有可能从基类列表中访问继承的类属性?

3 个答案:

答案 0 :(得分:2)

您需要将Entity个实例投射到EntityObject个实例,因为Position字段确实不属于Entity

所以:

var entityObjectInEntityList = (EntityObject)entityList[0]

将为您提供正确的类型,然后您可以访问.Position字段。

如评论中所述,您还可以通过以下方式测试类型/执行:

if(entityList[0] is EntityObject)
  

只是测试类型 - 通常避免,因为你仍然需要强制转换以获得正确的类型并且涉及开销

var item = entityList[0] as EntityObject;
if (item != null)
{
   var position = item.Position;
}

OR与C#6

var position = (entityList[0] as EntityObject)?.Position;
  

使用as关键字执行强制转换,如果失败则返回null。

正如Henk指出的那样,为了怜悯,你显然试图以EntityType属性的形式在你的班级中包含一些类型信息。

您可以在运行时确定对象的类型:

var type = instance.GetType();

因此:

if(itemInList.GetType() == typeof(EntityObject))

会告诉你实例的类型,但是使用像派生类的类型检查这样的东西通常都是一种气味。

假设您在Entity上不需要任何基本功能,我建议您改用接口方式。

我建议在这里查看:Interface vs Base class

答案 1 :(得分:0)

这是因为您已将列表声明为List<Entity>,但您尝试将其用作List<EntityObject>

我认为在您的情况下,您应该将列表声明为List&lt; EntityObject&GT;

另一种方法是将元素转换为EntityObject,如下所示:

((EntityObject )entityList[i]).position = Vector2.One;

你采取什么方式取决于你的商业模式,你的偏好,语义和你的建议。在这种情况下,问题是:

  • 为什么您将列表定义为List<Entity>,然后将其作为List<Entitybject>进行管理?

答案 2 :(得分:0)

我同意Facundo La Rocca(下图),您必须在访问其属性之前将对象强制转换为您要使用的类型。但是,如果要添加多个不同的EntityTypes(对象,字符等),则仍可以将其保留为实体的基本列表。您只需要确保对于列表中的每个不同类型的实体,您检查(并转换)它是哪一个:

public static void Main(string[] args){
    var entityList = new List<Entity>();
    entityList.Add(new EntityObject()); 

    for(int i = 0; i < entityList.Count; i++) {
        if(entityList[i] is EntityObject)
            ((EntityObject)entityList[i]).position = Vector2.One;
        else if (entityList[i] is EntityCharacter)
            ((EntityCharacter)entityList[i].characterProperty = someValueToSet;
    }