By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,454 Members | 3,209 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,454 IT Pros & Developers. It's quick & easy.

Casting up to inheriting class from base?

P: n/a
Say I have a class inheriting some base class:

BaseClass
{
void Foo()
{
Update();
}
}
Class1 : BaseClass
{
void Update(){}
}
How can I have the base class know which instance class has inherited
it and use a method in the instance class? Only certain types of
classes will use the base and those classes will always have an
Update() method.

Thanks,
Brett

Jul 6 '06 #1
Share this Question
Share on Google+
10 Replies


P: n/a
One way of doing this is to use an interface implemented in the
inheriting class. In the base, do this:

(( IMyClass )this).Update();

I'm interested in any better methods.

Thanks,
Brett

Jul 6 '06 #2

P: n/a

Brett Romero wrote:
Say I have a class inheriting some base class:

BaseClass
{
void Foo()
{
Update();
}
}
Class1 : BaseClass
{
void Update(){}
}
How can I have the base class know which instance class has inherited
it and use a method in the instance class? Only certain types of
classes will use the base and those classes will always have an
Update() method.
Maybe I'm missing something, but why can't you just make the base class
abstract, like this:

abstract BaseClass
{
void Foo()
{
Update();
}

abstract void Update()
{ ... }
}

?

Jul 6 '06 #3

P: n/a
Hi Brett,
I am curious why you have Foo( ) in BaseClass if Update( ) might not
exist to be called? Would it just make more sense to put Foo( ) in the
subclass? It seems like you might want to reconsider your design --
otherwise you are getting into "downcasting" (casting from a baseclass
to a derived class). Usually when I run into that, I take it as a hint
that it's time to refactor the code...

Also, what will Foo( ) do if it determines that the derived class does
not implement Update( ) ? If it just does nothing, then maybe you
should have a virtual Update( ) in the BaseClass that simply does
nothing, then override that function in the subclass.

Not that I'm recommending this, but to answer your question you can
always use the "is" keyword to check what type you're dealing with.
For example:

class Base
{
public void Foo()
{
if (this is Derived)
{
Derived d = (Derived)this;
d.Update();
}
}
}

class Derived : Base
{
public void Update()
{
Console.WriteLine("I am derived");
}
}

class Program
{
static void Main(string[] args)
{
Derived d = new Derived();
d.Foo(); // prints "I am derived"

Base b = new Base();
b.Foo(); // prints nothing
}
}

Hope that helps,
John

Brett Romero wrote:
One way of doing this is to use an interface implemented in the
inheriting class. In the base, do this:

(( IMyClass )this).Update();

I'm interested in any better methods.

Thanks,
Brett
Jul 6 '06 #4

P: n/a
Bruce is right - make Update an abstract method of BaseClass.

--
Adam Clauss
Jul 6 '06 #5

P: n/a

"Brett Romero" <ac*****@cygen.comwrote in message
news:11**********************@m38g2000cwc.googlegr oups.com...
Say I have a class inheriting some base class:

BaseClass
{
void Foo()
{
Update();
}
}
Class1 : BaseClass
{
void Update(){}
}
How can I have the base class know which instance class has inherited
it and use a method in the instance class? Only certain types of
classes will use the base and those classes will always have an
Update() method.
It's hard for me to say for sure (since "instance class" isn't really
correct - do you mean "derived class"?), but it's possible you just want to
make Foo() virtual.

///ark
Jul 6 '06 #6

P: n/a
>>I am curious why you have Foo( ) in BaseClass if Update( ) might not
exist to be called?

Update() will always exist.
John, I don't know what the type will be so this code doesn't work:

public void Foo()
{
if (this is Derived)
{
Derived d = (Derived)this;
d.Update();
}
}

I was trying to provide a simple example but the code does this:

public class BaseClass<T>{...}

public class MyClass: BaseClass<Person>, IClass<Person>{...}

I guess I'm not sure how your code would apply in this case.

In the end, how is your technique any better tham what I'm doing? We
are both still casting.

I can't use abstract because the base class has method bodies that do
something. In other words, it isn't an abstract class.
Thanks,
Brett

Jul 6 '06 #7

P: n/a
Brett Romero wrote:
>>>I am curious why you have Foo( ) in BaseClass if Update( ) might not
exist to be called?

Update() will always exist.
John, I don't know what the type will be so this code doesn't work:

public void Foo()
{
if (this is Derived)
{
Derived d = (Derived)this;
d.Update();
}
}

I was trying to provide a simple example but the code does this:

public class BaseClass<T>{...}

public class MyClass: BaseClass<Person>, IClass<Person>{...}

I guess I'm not sure how your code would apply in this case.

In the end, how is your technique any better tham what I'm doing? We
are both still casting.

I can't use abstract because the base class has method bodies that do
something. In other words, it isn't an abstract class.
Thanks,
Brett
Hi Brett,
Update() will always exist.
I know you say that, but the compiler doesn't know that. It is conceivable
that you could create a derived class that does not implement an Update()
method. You need to instruct the compilre that Update() will always exist.

To do this, you define your base class as being abstract, and your Update()
method as abstract:

public abstract class BaseClass
{
public void Foo()
{
Update();
}

public abstract void Update();
}

An abstract class cannot be instantiated, however, and if you require this
functionality, remove the abstract modifiers, and define the Update()
method as virtual, and in your base class, provide no implementation:

public class BaseClass
{
public void Foo()
{
Update();
}

public virtual void Update()
{
}
}

Now, any derived classes from the abstract version MUST override Update():

public class DerivedClass : BaseClass
{
public override void Update()
{
// Implementation
}
}

Or, derived classes from the virtual version MAY override Update():

public class DerivedClass : BaseClass
{
public override void Update()
{
// Implementation
}
}

--
Hope this helps,
Tom Spink
Jul 6 '06 #8

P: n/a

Brett Romero wrote:
I can't use abstract because the base class has method bodies that do
something. In other words, it isn't an abstract class.
You are mistaken as to what an abstract class is.

An abstract class can have methods and properties that do things, just
like a normal class. The only thing that makes it abstract is that
there is _at least one_ method / property / event / etc. that isn't
defined in the class and so must be defined in child classes.

The only reason that you couldn't have BaseClass be abstract is if
there is some situation in which you have to instantiate a base class
instance. If all you ever want is child class instances then BaseClass
can be abstract.

Jul 6 '06 #9

P: n/a
Hi Brett,
I guess I don't understand your question. The way your original sample
was written, it would not compile because Update( ) is not available to
the base class. From your original post,
How can I have the base class know which instance class has inherited
it and use a method in the instance class? Only certain types of
classes will use the base and those classes will always have an
Update() method.
I thought you wanted a way to figure out which subclasses had the
Update( ) method that could be called, and in a way that the code would
compile. And I assumed you didn't want to add Update( ) to the base
class for some reason (although, as others have pointed out, making
this a virtual or abstract member would also solve your problem).

As for the "we're both still casting" question. Well, of course --
there is no way around it. If the Update( ) member does not exist in
the base class, you're going to need a different type to perform the
call. The only difference is that my sample will not attempt to cast
if the derived type doesn't have the Update( ) member (no runtime
error).

Since you say that Update( ) will always exist, I think I agree with
the other comments here that it should be an abstract or virtual method
in the base class.

Best,
John

Brett Romero wrote:
>I am curious why you have Foo( ) in BaseClass if Update( ) might not
exist to be called?

Update() will always exist.
John, I don't know what the type will be so this code doesn't work:

public void Foo()
{
if (this is Derived)
{
Derived d = (Derived)this;
d.Update();
}
}

I was trying to provide a simple example but the code does this:

public class BaseClass<T>{...}

public class MyClass: BaseClass<Person>, IClass<Person>{...}

I guess I'm not sure how your code would apply in this case.

In the end, how is your technique any better tham what I'm doing? We
are both still casting.

I can't use abstract because the base class has method bodies that do
something. In other words, it isn't an abstract class.
Thanks,
Brett
Jul 7 '06 #10

P: n/a
I went with making the class abstract and certain methods in the class
abstract (those that were in the interface). I've completely dropped
the interface and all is working fine. All of the casting has gone
away as well.

Thanks all.
Brett

Jul 7 '06 #11

This discussion thread is closed

Replies have been disabled for this discussion.