繁体   English   中英

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

[英]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_bodyOBlock类中引用this.m_body ,都要分配属于OBlockm_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM