[英]Accessing fields of derived classes from a List of a base class
我正在使用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);
}
}
我只是将这些方法,字段等放入其中,以便我可以在List中访问它们的重写版本
所以我重写的版本看起来像这样:OBlock.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
我要做的是访问列表中任何Block的m_body,无论使用何种类型
blocks[index].m_body.DOSTUFF();
显然m_body总是空的......
public new Body m_body; //这是正确的吗?
没有! 这声明了第二个存储空间 - 所以你有Block的m_body和OBlock的m_body,你只需要初始化一个非null。 m_body的特定引用将解决的确切规则可能太无聊而无法理解。
您可能应该完全删除上面的行,并花些时间熟悉继承的基础知识,例如http://msdn.microsoft.com/en-gb/library/ms173149.aspx
public new Body m_body;
这隐藏了基类的m_body。 所以基本上你是在派生类(不是基类)中定义m_body的新实例。 所以我认为这就是你的基类m_body将为null的原因,因为它从未被初始化。
因此,删除该特定行,因为对于每个派生类,m_body已经定义为所有派生自Block类。 有关更多详细信息,请阅读此MSDN文章 。
public new Body m_body;
这是不对的。 你的Block
类中的m_body
(你应该标记为abstract
btw)在从它派生的所有类中都是可见的。 你现在正在做的事情被称为隐藏(应该总是避免imo),这会导致各种并发症。
你现在已经做到了这一点,每个OBlock
有两个成员m_body
,一个属于Block
,一个属于OBlock
。 它使得无论this.m_body
在OBlock
类中引用this.m_body
,都要分配属于OBlock
的m_body
字段,而只在Block
声明m_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
是从它派生的所有类继承的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.