Inheritance and Interfaces

G

GSL

I need help understanding why the following code causes an
InvalidCastException?

//I created an Interface
public interface IFoo
{
string a {get;}
}
//Then a class that implements the interface
public class Foo: IFoo
{
string a {get "something";}
}
//Then a special class that derives from Foo and adds additional methods
public class MyFoo: Foo
{
string b {get "something else";}
}

Why does the following line of code not work?
IFoo foo = new Foo();
MyFoo myFoo = (MyFoo)foo; // <- InvalidCastException!

Thanks.
 
R

Randy A. Ynchausti

GSL,

Basically because a Foo is not a MyFoo (Foo does not inherit from MyFoo).
Therefore, trying to cast a Foo to a MyFoo will result in an
InvalidCastException.

Note however, that a MyFoo is a Foo (MyFoo inherits from Foo). Therefore,
one can cast a MyFoo to a Foo without throwing an InvalidCastException.

Regards,

Randy
 
G

Guest

Because they do not implement the same interface. If your Myfoo also
implements Ifoo then you can do that.
I like the Foo examples.... they are all over the places for beginners.

The base class implements the interface so the derived class does to.

In any case, the interface is not relevent here.
 
G

Guest

IFoo foo = new Foo();
MyFoo myFoo = (MyFoo)foo; // <- InvalidCastException!

The interface is not the problem here. The existence of the interface makes
the example more complicated so it is harder to see what is going on.

The problem is that the object is a Foo since you said "new Foo()". Casting
does not magically change an object from one type to another. You created a
Foo and it will be a Foo for its entire life.

The cast asks the runtime to give you a MyFoo reference to the Foo object.
Since the object is not in fact a MyFoo, the cast fails.
 
P

Peter

I created a collection class (FooCollection), which is the base class for
specialty collections (MyFooCollection). When I add a new object to the
specialty collection (base.Add()) I'd like the result to be a MyFoo, not a
Foo. So, I tried to create an Interface IFoo, thinking that if the base
class returned the Interface I could cast it to a MyFoo, which is a special
version of Foo. I'm trying to find a way to do this where I don't have to
re-write all of the code for Foo class in each MyFoo, because MyFoo just
extends the base class it doesn't hide anything.

What is the right way of doing this?

Thanks for the help.
 
G

GSL

I created a collection class (FooCollection), which is the base class for
specialty collections (MyFooCollection). When I add a new object to the
specialty collection (base.Add()) I'd like the result to be a MyFoo, not a
Foo. So, I tried to create an Interface IFoo, thinking that if the base
class returned the Interface I could cast it to a MyFoo, which is a special
version of Foo. I'm trying to find a way to do this where I don't have to
re-write all of the code for Foo class in each MyFoo, because MyFoo just
extends the base class it doesn't hide anything.

What is the right way of doing this?

Thanks for the help.
 
J

Jon Skeet [C# MVP]

Peter said:
I created a collection class (FooCollection), which is the base class for
specialty collections (MyFooCollection). When I add a new object to the
specialty collection (base.Add()) I'd like the result to be a MyFoo, not a
Foo.

What kind of object are you adding though?
So, I tried to create an Interface IFoo, thinking that if the base
class returned the Interface I could cast it to a MyFoo, which is a special
version of Foo.

You can only cast it if it *is* a MyFoo, or if there's a conversion
defined between the declared type and MyFoo.
I'm trying to find a way to do this where I don't have to
re-write all of the code for Foo class in each MyFoo, because MyFoo just
extends the base class it doesn't hide anything.

What is the right way of doing this?

It's hard to say without knowing more about the real life situation, to
be honest. It may well be that the best way isn't to use inheritance at
all, for instance, but to use composition instead.
 
S

SP

GSL said:
I created a collection class (FooCollection), which is the base class for
specialty collections (MyFooCollection). When I add a new object to the
specialty collection (base.Add()) I'd like the result to be a MyFoo, not a
Foo. So, I tried to create an Interface IFoo, thinking that if the base
class returned the Interface I could cast it to a MyFoo, which is a
special
version of Foo. I'm trying to find a way to do this where I don't have to
re-write all of the code for Foo class in each MyFoo, because MyFoo just
extends the base class it doesn't hide anything.

What is the right way of doing this?

You can add any class that derives from Foo to your FooCollection. However
you will need to cast it back to the correct MyFoo. When I do this I have an
indexer that returns the derived type or null if it is not of that type.

public MyFoo MyFoo[int index]
{
get
if(this.InnerList[index] isMyFoo)
return (MyFoo)this.InnerList[index];
else
return null; ...

public MyOtherFoo MyOtherFoo[int index]
{
get
if(this.InnerList[index] isMyOtherFoo)
return (MyOtherFoo)this.InnerList[index];
else
return null;

SP
 

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