Problem with Method handling a BaseClass parameter

A

Andreas Schmitt

I have a problem here. I've read a book about C# already and got the
basics of how the language handles polymorphism I think but I ran into a
problem here that I simply never even thought of as a problem coming
from C++:

I wrote some code similar to this:

abtract public class Base
{
}

public class DerivedA : Base
{
}

public class DerivedB : Base
{
}



public class MyClass
{
public void HandleSomething(DerivedA whatever)
{}


public void HandleSomething(DerivedB whatever)
{}
}


public class MyClassB
{
public void HandleSomething(Base whatever)
{
myThing.HandleSomething(whatever);
}

private MyClass myThing;
}


Doing this I get the error that in MyClassB's method 'HandleSomething'
the parameter whatever cannot be converted to DerivedA or DerivedB
What's the logical reason for this error? The whole point of using a
common base class here was to enable me to handle all cases in one
method. Why does the compiler check this in this way? there will never
be a parameter that is just a "Base" because Base is abstract...

What's the correct way of doing this in C#?
 
N

Nicholas Paldino [.NET/C# MVP]

Andreas,

You have the example kind of turned around. It really should be this:

abtract public class Base
{
}

public class DerivedA : Base
{
}

public class DerivedB : Base
{
}



public class MyClass
{
public void HandleSomething(DerivedA whatever)
{
myClassB.HandleSomething(whatever);
}


public void HandleSomething(DerivedB whatever)
{
myClassB.HandleSomething(whatever);
}

private MyClassB myClassB;
}


public class MyClassB
{
public void HandleSomething(Base whatever)
{
// Do your logic here.
}
}

This example shows the advantages of polymorphism. With the one you
coded, you had a base class. The compiler can only know about classes that
the base class derives from (in other words, its parents) not about other
classes that derive from that class. For example, many classes can derive
from Base, and it is a one-to-many relationship. Because of that, the
compiler doesn't know which one to pass, hence the need to switch it around.

Hope this helps.
 
A

Andreas Schmitt

Nicholas said:
You have the example kind of turned around. It really should be this:

My example is the way I want to use it and the way it would work in C++
and I have no idea why it does not work in C#.
This example shows the advantages of polymorphism. With the one you
coded, you had a base class. The compiler can only know about classes that
the base class derives from (in other words, its parents) not about other
classes that derive from that class.

Why must it know? I tell the compiler what function I want not to check
if everything could possibly work under all conditions. I don't care if
the compiler knows all derived classes. I do.
Hope this helps.

Sorry but it does not.
I still don't get why C# must be so strict about this. If I cannot use a
Base Class pointer (and those strange C# referenece types are supposed
to be exactly that according to every C# information I read so far) to
transport any object that is an instance of a derived class of the base
then what are Base class pointers for anyway?
if I can't get this to work I'll have to overload the handle method for
every single derived class that exists although that method does nothing
but call another method of a different class in which the overloading
becomes necessary. For that one method I'd overload 20 methods which all
do exactly the same. What's the sense of that?
I begin to really dislike C# and its compiler always telling me what
value can't be converted to whatother and what conversion might not be
safe and whatever. Am I the programmer or the compiler?
(Ignore the outburst, just a frustrated C++ lover talking)

Any further help would be appreciated
 
A

Andreas Schmitt

Andreas said:
Sorry but it does not.
I still don't get why C# must be so strict about this. If I cannot use a
Base Class pointer (and those strange C# referenece types are supposed
to be exactly that according to every C# information I read so far) to
transport any object that is an instance of a derived class of the base
then what are Base class pointers for anyway?
if I can't get this to work I'll have to overload the handle method for
every single derived class that exists although that method does nothing
but call another method of a different class in which the overloading
becomes necessary. For that one method I'd overload 20 methods which all
do exactly the same. What's the sense of that?
I begin to really dislike C# and its compiler always telling me what
value can't be converted to whatother and what conversion might not be
safe and whatever. Am I the programmer or the compiler?
(Ignore the outburst, just a frustrated C++ lover talking)

Any further help would be appreciated

I take everything back, I'm an idiot. This doesn't work in C++ either of
course.
 
J

Jon Skeet [C# MVP]

Andreas Schmitt said:
My example is the way I want to use it and the way it would work in C++
and I have no idea why it does not work in C#.

I'd be very surprised if it really *did* work in C++. Could you provide
an example which compiles in C++?
Why must it know? I tell the compiler what function I want not to check
if everything could possibly work under all conditions. I don't care if
the compiler knows all derived classes. I do.

Overloading is performed at compile-time, not execution time. The
compiler needs to know which of the methods to call, and it can't find
any that will definitely work.

The normal way round this is to use double-dispatch. See
http://en.wikipedia.org/wiki/Double_dispatch#Double_dispatch_in_C.2B.2B
for some info on this.
Sorry but it does not.
I still don't get why C# must be so strict about this. If I cannot use a
Base Class pointer (and those strange C# referenece types are supposed
to be exactly that according to every C# information I read so far) to
transport any object that is an instance of a derived class of the base
then what are Base class pointers for anyway?

You can - you just can't change the fact that overloading is performed
at compile-time.
if I can't get this to work I'll have to overload the handle method for
every single derived class that exists although that method does nothing
but call another method of a different class in which the overloading
becomes necessary. For that one method I'd overload 20 methods which all
do exactly the same. What's the sense of that?

Use polymorphism instead. Put an empty virtual method in the base
class, and override it in each method you actually want to do something
in. Then just call whatever.SomeMethod(myThing).
I begin to really dislike C# and its compiler always telling me what
value can't be converted to whatother and what conversion might not be
safe and whatever. Am I the programmer or the compiler?
(Ignore the outburst, just a frustrated C++ lover talking)

I think you're complaining about something you couldn't do in C++
either though.
 

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