从基类列表中访问派生类的字段
本文关键字:字段 派生 访问 基类 列表 | 更新日期: 2023-09-27 17:57:06
我正在使用C#和XNA 4.0,以及Farseer Physics Engine(与Box2D非常相似),并且有一个Block类,我从中派生OBlock,LBlock等。
块如下:
class Block
{
public Body m_body;
public virtual void Draw(SpriteBatch spriteBatch) { }
public virtual void RemoveBody(World world)
{
//world.RemoveBody(m_body);
}
}
我只把这些方法、字段等放进去,这样我就可以在列表中访问它们被覆盖的版本
所以我被覆盖的版本看起来像这样:奥布洛克.cs
class OBlock : Block
{
private static Texture2D blockImg; //I load this in LoadContent so I don't have loads of Texture2Ds
public new Body m_body; //Is this right?
public OBlock(World world, Vector2 position)
{
m_body = BodyFactory.CreateBody(world, position); // Create the body, changing it from null
FixtureFactory.AttachRectangle(Game1.blockSide *2, Game1.blockSide *2, 1.0f, new Vector2(0, 0), m_body); //This bit changes between classes
m_body.BodyType = BodyType.Dynamic;
}
public override void RemoveBody(World world)
{
world.RemoveBody(m_body);
}
public static void LoadImage(Texture2D tex)
{
OBlock.blockImg = tex;
}
public override void Draw(SpriteBatch spriteBatch)
{
Vector2 position = m_body.Position * Game1.MetreInPixels;
Vector2 origin = new Vector2(blockImg.Width / 2, blockImg.Height / 2);
float rotation = m_body.Rotation;
spriteBatch.Begin();
spriteBatch.Draw(blockImg, position, null, Color.White, rotation, origin, Game1.BLOCK_SCALE, SpriteEffects.None, 1);
spriteBatch.End();
base.Draw(spriteBatch);
}
}
还有LBlock,ZBlock等,除了我评论的那一点之外,它们看起来都非常相似。
然后我把它们都放进去
List<Block> blocks //As a field in Game1
blocks = new List<Block>(); // In LoadContent after loading images
我正在尝试做的是访问列表中任何块的m_body,无论使用哪种类型
blocks[index].m_body.DOSTUFF();
显然m_body总是空的...
公共新机构m_body;//这是对的吗?
不!这声明了第二位存储 - 所以你有 Block 的 m_body 和 OBlock 的m_body,你只初始化一个为非空。对m_body的特定引用将解析为什么的确切规则可能太无聊而无法理解。
您可能应该完全删除上面的行,并花一些时间熟悉继承的基础知识,例如 http://msdn.microsoft.com/en-gb/library/ms173149.aspx
public new Body m_body;
这是不对的。Block
类中的m_body
(您应该将其标记为abstract
顺便说一句)在派生它的所有类中都可见。你现在正在做的事情被称为隐藏(imo应该始终避免),这会导致各种并发症。
您现在已经做到了,每个OBlock
都有两个成员m_body
,一个属于Block
,一个属于OBlock
。这样,每当您在OBlock
类中引用this.m_body
时,您都会分配属于OBlock
的m_body
字段,而m_block
单独声明Block
。这是隐藏成员带来的奇怪复杂性之一:
Block myBlock = new OBlock();
// myBlock.m_block is null, because myBlock is of type block, and remember,
// the m_block belonging to Block is never assigned to, only the one belonging
// to OBlock
而这将按预期工作:
OBlock myOBlock = new OBlock();
// myOBlock.m_block isn't null, because it was assigned to in the constructor.
所以避免隐藏!删除
public new Body m_body;
从你的代码文件中,你很好,因为Block
中声明的m_block
无论如何都会被派生的所有类继承。
public new Body m_body;
这将隐藏基类m_body。所以基本上你在派生类(不是基类)中定义一个新的m_body实例。所以我假设这就是你的基类m_body为空的原因,因为它永远不会初始化。
因此,请删除该特定行,因为对于每个派生类,m_body都已定义为所有派生自 Block 类。有关更多详细信息,请参阅此 MSDN 文章。