2

I've been doing some testing and came across something strange. Say I have this interface

interface IRobot
    {
         int Fuel { get; }
    }

As you can see, it's read only. So now i'm going to make a class that implements it

 class FighterBot : IRobot
    {

        public int Fuel { get; set; }
    }

Now you can read it and set it. So let's do some tests:

        FighterBot fighterBot;
        IRobot robot;
        IRobot robot2;
        int Fuel;
public Form1()
        {
            InitializeComponent();
            fighterBot = new FighterBot();
            robot = new FighterBot();
        }

First I did this:

 Fuel = fighterBot.Fuel;// Can get it
            fighterBot.Fuel = 10; //Can set it

That's to be expected, then I did this:

 Fuel = robot.Fuel; //Can get it
            robot.Fuel = 10; //Doesn't work, is read only

Also to be expected. But when I do this:

robot2 = robot as FighterBot;
            Fuel = robot2.Fuel; //Can get it
            robot2.Fuel = 10;//Doesn't work, is read only

Why doesn't it work? Isn't it treating the robot2 AS a FighterBot? Therefore, shouldn't it be able to set the Fuel?

Amicable
  • 3,115
  • 3
  • 49
  • 77
  • 1
    IRobot's Fuel is indeed readonly, that is correct! – David Mar 17 '13 at 13:34
  • It'll work if you say `var robot3 = robot as FighterBot;`. The C# compiler uses the declared type of the variable to determine what functions are available; assigning a new value to robot2 does not change the original declared type (which is still IRobot). – Morten Mertner Mar 17 '13 at 13:34

2 Answers2

3

Even though you are casting robot to FighterBot via the "as" statement, you are storing the result in a variable of type IRobot so Fuel is still read only.

You need to store the result of the conversion in a variable of type FighterBot:

var robot3 = robot as FighterBot;

Then it will work.

ChrisF
  • 134,786
  • 31
  • 255
  • 325
1
interface IRobot
{
     int Fuel { get; }
}

robot2 = robot as FighterBot;
Fuel = robot2.Fuel;

// robot2 is STILL stored as IRobot, so the interface allowed 
// to communicate with this object will be restricted by 
// IRobot, no matter what object you put in (as long as it implements IRobot)
robot2.Fuel = 10; // evidently, won't compile.

Some more context:

IRobot r = new FighterBot();
// you can only call method // properties that are described in IRobot

If you want to interact with the object and set properties, use the designed interface for it.

FigherBot r = new FighterBot();
r.Fuel = 10;
bas
  • 13,550
  • 20
  • 69
  • 146