从基类的List访问派生类的字段

时间:2013-02-03 09:22:26

标签: c# list inheritance syntax polymorphism

我正在使用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总是空的......

3 个答案:

答案 0 :(得分:2)

public new Body m_body; //这是对的吗?

没有!这声明了第二个存储空间 - 所以你有Block的m_body和OBlock的m_body,你只需要初始化一个非null。对于m_body的特定引用将解决的确切规则可能太无聊而无法理解。

您应该完全删除上面的行,并花一些时间来熟悉继承的基础知识,例如: http://msdn.microsoft.com/en-gb/library/ms173149.aspx

答案 1 :(得分:0)

public new Body m_body; 

这隐藏了基类的m_body。所以基本上你是在派生类(不是基类)中定义m_body的新实例。所以我认为这就是你的m_body基类是null的原因,因为它从未被初始化。

因此,删除该特定行,因为对于每个派生类,m_body已经定义为所有派生自Block类。有关详细信息,请浏览this MSDN article

答案 2 :(得分:0)

public new Body m_body;

这是不对的。 m_body类(您应该标记为Block btw)中的abstract在从中派生的所有类中都可见。你现在正在做的事情被称为隐藏(应该总是避免imo),这会导致各种并发症。

您现在已经做到这一点,以便每个OBlock有两个成员m_body,一个属于Block,一个属于OBlock。这样,只要您在this.m_body课程中引用OBlock,就可以指定属于m_body的{​​{1}}字段,并声明OBlockm_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; 中声明的m_block仍然是从它派生的所有类继承的。