Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this cast from interface to class failing?

Tags:

c#

casting

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?

like image 453
ssb Avatar asked Nov 09 '12 14:11

ssb


People also ask

Can a class be casted to an interface?

Yes, you can. If you implement an interface and provide body to its methods from a class. You can hold object of the that class using the reference variable of the interface i.e. cast an object reference to an interface reference.

Why we call it interface why not we can call it a class?

An interface is not a class. Writing an interface is similar to writing a class, but they are two various concepts. A class describes the attributes and behaviours of an object. An interface contains behaviours that a class implements.

What is casting to an interface?

A type cast—or simply a cast— is an explicit indication to convert a value from one data type to another compatible data type. A Java interface contains publicly defined constants and the headers of public methods that a class can define.


6 Answers

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.

like image 87
Mark Byers Avatar answered Oct 05 '22 12:10

Mark Byers


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;
}
like image 23
Rex M Avatar answered Oct 05 '22 13:10

Rex M


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

Try this:

((Player) moving).Color = Color.Red;
like image 20
Chayemor Avatar answered Oct 05 '22 13:10

Chayemor


You should add additional brackets:

((Player)moving).Color = Color.Red;
like image 44
Artem Vyshniakov Avatar answered Oct 05 '22 13:10

Artem Vyshniakov


You need parentheses around the cast and the variable:

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

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

like image 37
Joey Avatar answered Oct 05 '22 12:10

Joey


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;
}
like image 39
Tim Schmelter Avatar answered Oct 05 '22 14:10

Tim Schmelter