繁体   English   中英

访问子类(C#)中的成员变量

[英]Accessing member variable in subclass (C#)

我游戏中的所有对象都继承了我的Sprite类。 这是我使用的层次结构:

Sprite > StaticObject > MovingObject > 角色 > 播放器

我已经在我的主要游戏类中编写了一个函数,该函数可以搜索游戏中的所有对象并找到任何“ 玩家 ”对象。 如果找到了Player对象,则它将对象的速度值( v2Speed向量)打印到屏幕上。

foreach (var gameObject in GameInfo.gameInfo.gameObjects)
{
    if (gameObject.GetType() == typeof (Player))
    {
        string sPlayerPosition = string.Format("Player position: ({0:0.00},{1:0.00})", gameObject.v2Position.X, gameObject.v2Position.Y);
        DrawWithShadow(sPlayerPosition, new Vector2(10, 60));

        string sPlayerSpeed = string.Format("Player speed: ({0:0.00},{1:0.00})", gameObject.v2Speed.X, gameObject.v2Speed.Y);
        DrawWithShadow(sPlayerSpeed, new Vector2(10, 80));
    }
}

但是,这仅在将v2Speed放入基本Sprite类中时才有效。 我认为这是因为编译器希望在游戏正在搜索的每个对象中找到变量。 我不确定为什么会出现此问题,因为访问v2Speed的代码仅应用于已定义该向量的Player对象。 我真的不希望有v2Speed在比MovingObject类更高的任何一类,因为雪碧StaticObject对象永远不会移动,一旦游戏开始。

我的问题是,如果将v2Speed存储在MovingObject类而不是Sprite类中,该如何重写上面的代码来访问v2Speed

编译器仅知道gameObject属于Sprite类型(我想;很难确定)。 您的if条件不会改变这一点。

相反,您可以使用:

if (gameObject is Player player)
{
    // Now use player instead of gameObject
}

请注意,这需要C#7。如果仅使用C#6或更早版本,则可以使用:

Player player = gameObject as Player;
if (player != null)
{
    // ...
}

请注意,这与原始代码的行为略有不同-如果您有一个对象是Player子类的实例,则该对象不会在原始代码中被拾取,而在此代码中...你想要什么。

(按照Codor的回答,OfType OfType<Player>方法是一个很好的选择-尽管我会称呼循环变量player而不是gameObject ,但gameObject是您知道它是一个player ...)

可以使用Linq如下更改代码。

foreach (var gameObject in GameInfo.gameInfo.gameObjects.OfType<Player>())
{
    string sPlayerPosition
        = string.Format("Player position: ({0:0.00},{1:0.00})", 
                gameObject.v2Position.X, gameObject.v2Position.Y);
                DrawWithShadow(sPlayerPosition, new Vector2(10, 60));

    string sPlayerSpeed
        = string.Format("Player speed: ({0:0.00},{1:0.00})", 
                gameObject.v2Speed.X, gameObject.v2Speed.Y);
                DrawWithShadow(sPlayerSpeed, new Vector2(10, 80));

}

或者,可以在循环体内使用对Player的强制转换。

您需要进行类型转换,并且应该使用as进行转换as因为您不确定对象是否属于Player类型。

像这样:

foreach (var gameObject in GameInfo.gameInfo.gameObjects)
{
    var player = gameObject as Player;  // try to do Type Cast
    if (player != null)             // if true, then Type Cast has succeeded
    {
        string sPlayerPosition = string.Format("Player position: ({0:0.00},{1:0.00})", player.v2Position.X, player.v2Position.Y);
        DrawWithShadow(sPlayerPosition, new Vector2(10, 60));

        string sPlayerSpeed = string.Format("Player speed: ({0:0.00},{1:0.00})", player.v2Speed.X, player.v2Speed.Y);
        DrawWithShadow(sPlayerSpeed, new Vector2(10, 80));
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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