为什么从接口到类的转换失败?

ssb*_*ssb 9 c# casting

private Vector2 ResolveCollision(ICollidable moving, ICollidable stationary)
{
    if (moving.Bounds.Intersects(stationary.Bounds))
    {
        if (moving is Player)
        {
            (Player)moving.Color = Color.Red;
        }
    }
    // ...
}
Run Code Online (Sandbox Code Playgroud)

我有一个Player实现的类ICollidable.出于调试目的,我只是试图传递一堆ICollidables这种方法,并在玩家时做一些特殊的事情.然而,当我尝试做演员时Player,ICollidable我得到一个错误,告诉我ICollidable没有Color属性.

我不能以这种方式进行演员表演,或者我做错了什么?

Mar*_*ers 16

我建议使用as而不是is:

Player player = moving as Player;
if (player != null)
{
    player.Color = Color.Red;
}
Run Code Online (Sandbox Code Playgroud)

优点是您只进行一次类型检查.


您的代码不起作用的具体原因(如其他答案中所述)是由于运算符优先级.所述.操作者是一个主运营商具有比铸造操作者这是一个较高的优先级一元运算符.您的代码解释如下:

(Player)(moving.Color) = Color.Red;
Run Code Online (Sandbox Code Playgroud)

按照其他答案的建议添加括号可以解决此问题,但更改为使用as而不是is使问题完全消失.


Rex*_*x M 9

你的语法铸造ColorPlayer,没有moving.

((Player)mover).Color = Color.Red;
//^do the cast  ^access the property from the result of the cast
Run Code Online (Sandbox Code Playgroud)

而且,as往往更好一点.如果失败,结果是null:

var player = moving as Player;
if(player != null)
{
    player.Color = Color.Red;
}
Run Code Online (Sandbox Code Playgroud)