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

I have a class Player that implements ICollidable. For debugging purposes I'm just trying to pass a bunch of ICollidables to this method and do some special stuff when it's the player. However when I try to do the cast to Player of the ICollidable I get an error telling me that ICollidable doesn't have a Color property.

Am I not able to make a cast this way or am I doing something wrong?

yoozer8
  • 7,361
  • 7
  • 58
  • 93
ssb
  • 1,352
  • 3
  • 18
  • 40
  • 3
    Just a case of parantheses wrong: `((Player)moving).Color = ...` – Davio Nov 09 '12 at 14:12
  • 1
    you should say ((Player)moving).Color = Color.Red if Color is an attribute of Player – wxyz Nov 09 '12 at 14:13
  • 1
    My new problem is how I decide which answer to accept. I can never fault this site for being slow... – ssb Nov 09 '12 at 14:15
  • you should flip about 3 coins to figure that out. – wxyz Nov 09 '12 at 14:17
  • though you may have to do this many times as there are only 6 answers and 8 possibilities..aah..sure..just roll a dice – wxyz Nov 09 '12 at 14:18

6 Answers6

16

I'd suggest using as instead of is:

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

The advantage is that you only do the type check once.


The specific reason why your code doesn't work (as mentioned in other answers) is because of operator precedence. The . operator is a primary operator which has a higher precedence than the casting operator which is a unary operator. Your code is interpreted as follows:

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

Adding the parentheses as suggested by other answers solves this issue, but changing to use as instead of is makes the issue go away completely.

Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
9

Your syntax is casting Color to Player, not moving.

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

Also, as tends to be a little nicer. If it fails, the result is null:

var player = moving as Player;
if(player != null)
{
    player.Color = Color.Red;
}
Rex M
  • 142,167
  • 33
  • 283
  • 313
  • `is` and then a cast is virtually identical to `as` and then a null check. In neither case will an exception be thrown. – Servy Nov 09 '12 at 14:27
3

It's not that it's not working, it's the syntax that is "somewhat" wrong.

Try this:

((Player) moving).Color = Color.Red;
LarsTech
  • 80,625
  • 14
  • 153
  • 225
Chayemor
  • 3,577
  • 4
  • 31
  • 54
2

You should add additional brackets:

((Player)moving).Color = Color.Red;
Artem Vyshniakov
  • 16,355
  • 3
  • 43
  • 47
2

You need parentheses around the cast and the variable:

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

otherwise you're trying to cast moving.Color to Player.

Joey
  • 344,408
  • 85
  • 689
  • 683
2

You have forgotten one bracket:

change

 (Player)moving.Color = Color.Red;

to

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

You can also use the as operator to cast.

Player p = moving as Player;
if (p != null)
{
    p.Color = Color.Red;
}
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939