views:

3480

answers:

6

Is it possible to assign a base class object to a derived class reference with an explicit typecast in C#?.

I have tried it and it creates a run-time error.

+2  A: 

No it is not possible, hence your runtime error.

But you can assign an instance of a derived class to a variable of base class type.

ybo
+4  A: 

No. A reference to a derived class must actually refer to an instance of the derived class (or null). Otherwise how would you expect it to behave?

For example:

object o = new object();
string s = (string) o;
int i = s.Length; // What can this sensibly do?

If you want to be able to convert an instance of the base type to the derived type, I suggest you write a method to create an appropriate derived type instance. Or look at your inheritance tree again and try to redesign so that you don't need to do this in the first place.

Jon Skeet
It's a first: Jon Skeet writes code that doesn't compile!
Mike Powell
@Mike: The code compiles just fine. It falls over at execution time though :)
Jon Skeet
+1  A: 

Expanding on @ybo's answer - it isn't possible because the instance you have of the base class isn't actually an instance of the derived class. It only knows about the members of the base class, and doesn't know anything about those of the derived class.

The reason that you can cast an instance of the derived class to an instance of the base class is because the derived class actually already is an instance of the base class, since it has those members already. The opposite cannot be said.

Andy
A: 

You can cast a variable that is typed as the base-class to the type of a derived class; however, by necessity this will do a runtime check, to see if the actual object involved is of the correct type.

Once created, the type of an object cannot be changed (not least, it might not be the same size). You can, however, convert an instance, creating a new instance of the second type - but you need to write the conversion code manually.

Marc Gravell
A: 

No, see this question which I asked - http://stackoverflow.com/questions/694449/upcasting-in-net-using-generics

The best way is to make a default constructor on the class, construct and then call an Initialise method

Slace
+3  A: 

No, that's not possible since assigning it to a derived class reference would be like saying "Base class is a fully capable substitute for derived class, it can do everything the derived class can do", which is not true since derived classes in general offer more functionality than their base class (at least, that's the idea behind inheritance).

You could write a constructor in the derived class taking a base class object as parameter, copying the values.

Something like this:

public class Base {
    public int Data;

    public void DoStuff() {
        // Do stuff with data
    }
}

public class Derived : Base {
    public int OtherData;

    public Derived(Base b) {
        this.Data = b.Data;
        OtherData = 0; // default value
    }

    public void DoOtherStuff() {
        // Do some other stuff
    }
}

In that case you would copy the base object and get a fully functional derived class object with default values for derived members. This way you can also avoid the problem pointed out by Jon Skeet:

Base b = new Base();
Dervided d = new Derived();

b.DoStuff();    // OK
d.DoStuff();    // Also OK
b.DoOtherStuff();    // Won't work!
d.DoOtherStuff();    // OK

d = new Derived(b);  // Copy construct a Derived with values of b
d.DoOtherStuff();    // Now works!
Michael Barth