首先,我创建基类并继承类
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'的第一个参数可以找到(你是否错过了使用指令或者装配参考?)
是否有可能从基类列表中访问继承的类属性?
答案 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;
}