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

时间:2012-11-09 14:11:03

标签: c# casting

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

我有一个实现Player的课程ICollidable。出于调试目的,我只是尝试将一堆ICollidables传递给此方法,并在播放器时执行一些特殊操作。但是,当我尝试对Player的{​​{1}}进行投射时,我收到错误消息,告诉我ICollidable没有ICollidable属性。

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

6 个答案:

答案 0 :(得分:16)

我建议使用as代替is

Player player = moving as Player;
if (player != null)
{
    player.Color = Color.Red;
}

优点是你只进行一次类型检查。


您的代码不起作用的具体原因(如其他答案中所述)是由于operator precedence.运算符是主运算符,其优先级高于一元运算符的转换运算符。您的代码解释如下:

(Player)(moving.Color) = Color.Red;

根据其他答案的建议添加括号可以解决此问题,但更改为使用as代替is会使问题完全消失。

答案 1 :(得分:9)

您的语法是将Color投射到Player,而不是moving

((Player)mover).Color = Color.Red;
//^do the cast  ^access the property from the result of the cast

此外,as往往更好一些。如果失败,则结果为null

var player = moving as Player;
if(player != null)
{
    player.Color = Color.Red;
}

答案 2 :(得分:3)

并不是它不起作用,而是语法“有些”错误。

试试这个:

((Player) moving).Color = Color.Red;

答案 3 :(得分:2)

您应该添加其他括号:

((Player)moving).Color = Color.Red;

答案 4 :(得分:2)

你需要围绕演员和变量括号括号:

((Player)moving).Color = Color.Red;

否则您正在尝试将moving.Color投射到Player

答案 5 :(得分:2)

你忘记了一个括号:

变化

 (Player)moving.Color = Color.Red;

 ((Player)moving).Color = Color.Red;

您也可以使用as operator投射。

Player p = moving as Player;
if (p != null)
{
    p.Color = Color.Red;
}