Casting between two classes derived from the same base class

L

Lars-Erik Aabech

Hi!

I've got a small challenge with my class library. I've got an abstract base
class with some protected fields. It has two derived classes, and it should
be possible to cast these classes to each other. The variables to be
persisted are the ones from the base class.

It is possible to cast upwards, but I'm not allowed to cast downwards. The
only solution I found was to create explicit casting operators on each of
the derived classes. The first step is to cast the source object to the base
class, and then create a new instance of the target class based on the
fields of the base class. But since the fields are protected, I can't read
them. The solution as of now is to change the protected fields to internal
fields. It works, but now all classes in the assembly can see the fields,
and I don't want that. :p

Anyone got a better solution?

Lars-Erik
 
G

Guest

It is possible to cast upwards, but I'm not allowed to cast downwards.

that's correct. I think whenever you find yourself in a situation like
this, it's likely that your design is flawed.

but to do what you want, a copy constructor through inheritance will do the
trick

public class Base
{
protected int _i;

public Base()
{
}

public Base(Base clone)
{
this._i = clone._i;
}
}

public class Derived1 : Base
{
public void Set(int i)
{
this._i = i;
}
}

public class Derived2 : Base
{
public Derived2(Derived1 obj) : base(obj)
{
}

public int Get()
{
return this._i;
}
}

public class MyClass
{
public static void Main()
{
Derived1 obj1 = new Derived1();
obj1.Set( 100 );
Derived2 obj2 = new Derived2( obj1 );
Console.WriteLine( obj2.Get() );
}
}
 
C

Christoph Nahr

It is possible to cast upwards, but I'm not allowed to cast downwards.

Downcasting is only allowed to the actual type or one of its parents.
It can't be any other way since a "sibling type" can have totally
different fields, so an actual data conversion is needed which can't
be automated. Casts along the inheritance hierarchy never change
data, they merely give you different views on the same data.

You can do a copy constructor like Daniel suggested, though the more
"standard" way to do this is to create a static "FromFoo" method:

public class Bar {
public static Bar FromFoo(Foo foo) {
Bar bar = new Bar(...);
bar.SomeBarData = SomeConverter(foo.SomeFooData);
return bar;
}
}

That's assuming that Foo and Bar are your two sibling classes. No
chance to access Foo's protected fields from Bar, though -- unless you
opt to use reflection, which is slow and convoluted.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top