473,396 Members | 1,998 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Should this type of method overload work in C#?

public class Base
{
}

public class Derived : Base
{
}

public class Service
{
public void Send(Base baseObject)
{
// send baseObject
Console.Out.WriteLine("Called public void Send(Base baseObject)
signature");
}

public void Send(Subclass derivedObject)
{
// send derivedObject
Console.Out.WriteLine("Called public void Send(Subclass derivedObject)
signature");
}
}

public class MainClass
{
public static void Main(string[] args)
{
Base baseObject = new Base();
Derived derivedObject = new Derived();

Service service = new Service();

// this calls public void Send(Base baseObject) as expected
service.Send(baseObject);

// this calls public void Send(Base baseObject),
// but it should call public void Send(Subclass derivedObject),
// shouldn't it???
service.Send(derivedObject);
}
}

I expect this to work, but I tested it at runtime, verifying that the
instance is of the Derived class and it still calls the signature with the
base class.

thanks,

Dave Raskin
Nov 17 '05 #1
19 1905
Howdy. I believe I got it to work properly (as you expected) for me.
Here's the code I used (slightly modified to get it to compile). Output at
the end.
//--------------------------------------------------------------start code
using System;

public class Base
{
}

public class Derived : Base
{
}

public class Service
{
public void Send(Base baseObject)
{
// send baseObject
Console.WriteLine("Called public void Send(Base baseObject) signature");
}

public void Send(Derived derivedObject)
{
// send derivedObject
Console.WriteLine("Called public void Send(Subclass derivedObject)
signature");
}
}

public class MainClass
{
public static void Main(string[] args)
{
Base baseObject = new Base();
Derived derivedObject = new Derived();

Service service = new Service();

// this calls public void Send(Base baseObject) as expected
service.Send(baseObject);

// this calls public void Send(Base baseObject),
// but it should call public void Send(Subclass derivedObject),
// shouldn't it???
service.Send(derivedObject);
}
}
//--------------------------------------------------------------end code
And here's the output I see.

C:\temp>basetesting
Called public void Send(Base baseObject) signature
Called public void Send(Subclass derivedObject) signature

C:\temp>
Nov 17 '05 #2
Howdy. I believe I got it to work properly (as you expected) for me.
Here's the code I used (slightly modified to get it to compile). Output at
the end.
//--------------------------------------------------------------start code
using System;

public class Base
{
}

public class Derived : Base
{
}

public class Service
{
public void Send(Base baseObject)
{
// send baseObject
Console.WriteLine("Called public void Send(Base baseObject) signature");
}

public void Send(Derived derivedObject)
{
// send derivedObject
Console.WriteLine("Called public void Send(Subclass derivedObject)
signature");
}
}

public class MainClass
{
public static void Main(string[] args)
{
Base baseObject = new Base();
Derived derivedObject = new Derived();

Service service = new Service();

// this calls public void Send(Base baseObject) as expected
service.Send(baseObject);

// this calls public void Send(Base baseObject),
// but it should call public void Send(Subclass derivedObject),
// shouldn't it???
service.Send(derivedObject);
}
}
//--------------------------------------------------------------end code
And here's the output I see.

C:\temp>basetesting
Called public void Send(Base baseObject) signature
Called public void Send(Subclass derivedObject) signature

C:\temp>
Nov 17 '05 #3
Hi Dave,

Service doesn't have an overload with a Derived parameter, so the compiler
used a best match that took the overload with the Base parameter. From the
information you've given, I can't tell what SubClass is. However, if you
change the definition of Send(SubClass derivedObject) to this, you could get
what you expect:

public void Send(Derived derivedObject)
{
// send derivedObject
Console.Out.WriteLine("Called public void Send(Derived derivedObject)
signature");
}

Joe
--
http://www.csharp-station.com

"Dave Raskin" <Dave Ra****@discussions.microsoft.com> wrote in message
news:0A**********************************@microsof t.com...
public class Base
{
}

public class Derived : Base
{
}

public class Service
{
public void Send(Base baseObject)
{
// send baseObject
Console.Out.WriteLine("Called public void Send(Base baseObject)
signature");
}

public void Send(Subclass derivedObject)
{
// send derivedObject
Console.Out.WriteLine("Called public void Send(Subclass derivedObject)
signature");
}
}

public class MainClass
{
public static void Main(string[] args)
{
Base baseObject = new Base();
Derived derivedObject = new Derived();

Service service = new Service();

// this calls public void Send(Base baseObject) as expected
service.Send(baseObject);

// this calls public void Send(Base baseObject),
// but it should call public void Send(Subclass derivedObject),
// shouldn't it???
service.Send(derivedObject);
}
}

I expect this to work, but I tested it at runtime, verifying that the
instance is of the Derived class and it still calls the signature with the
base class.

thanks,

Dave Raskin

Nov 17 '05 #4
Hi Dave,

Service doesn't have an overload with a Derived parameter, so the compiler
used a best match that took the overload with the Base parameter. From the
information you've given, I can't tell what SubClass is. However, if you
change the definition of Send(SubClass derivedObject) to this, you could get
what you expect:

public void Send(Derived derivedObject)
{
// send derivedObject
Console.Out.WriteLine("Called public void Send(Derived derivedObject)
signature");
}

Joe
--
http://www.csharp-station.com

"Dave Raskin" <Dave Ra****@discussions.microsoft.com> wrote in message
news:0A**********************************@microsof t.com...
public class Base
{
}

public class Derived : Base
{
}

public class Service
{
public void Send(Base baseObject)
{
// send baseObject
Console.Out.WriteLine("Called public void Send(Base baseObject)
signature");
}

public void Send(Subclass derivedObject)
{
// send derivedObject
Console.Out.WriteLine("Called public void Send(Subclass derivedObject)
signature");
}
}

public class MainClass
{
public static void Main(string[] args)
{
Base baseObject = new Base();
Derived derivedObject = new Derived();

Service service = new Service();

// this calls public void Send(Base baseObject) as expected
service.Send(baseObject);

// this calls public void Send(Base baseObject),
// but it should call public void Send(Subclass derivedObject),
// shouldn't it???
service.Send(derivedObject);
}
}

I expect this to work, but I tested it at runtime, verifying that the
instance is of the Derived class and it still calls the signature with the
base class.

thanks,

Dave Raskin

Nov 17 '05 #5
You're right, the second Send() signautre should have Derived as param, not
Subclass.

Thanks for your answer. My case didn't work, although what I presented here
is a simplified situation, which I thought was essentially the same, but may
be I missed something. I will take a look.

"Flip" wrote:
Howdy. I believe I got it to work properly (as you expected) for me.
Here's the code I used (slightly modified to get it to compile). Output at
the end.
//--------------------------------------------------------------start code
using System;

public class Base
{
}

public class Derived : Base
{
}

public class Service
{
public void Send(Base baseObject)
{
// send baseObject
Console.WriteLine("Called public void Send(Base baseObject) signature");
}

public void Send(Derived derivedObject)
{
// send derivedObject
Console.WriteLine("Called public void Send(Subclass derivedObject)
signature");
}
}

public class MainClass
{
public static void Main(string[] args)
{
Base baseObject = new Base();
Derived derivedObject = new Derived();

Service service = new Service();

// this calls public void Send(Base baseObject) as expected
service.Send(baseObject);

// this calls public void Send(Base baseObject),
// but it should call public void Send(Subclass derivedObject),
// shouldn't it???
service.Send(derivedObject);
}
}
//--------------------------------------------------------------end code
And here's the output I see.

C:\temp>basetesting
Called public void Send(Base baseObject) signature
Called public void Send(Subclass derivedObject) signature

C:\temp>

Nov 17 '05 #6
You're right, the second Send() signautre should have Derived as param, not
Subclass.

Thanks for your answer. My case didn't work, although what I presented here
is a simplified situation, which I thought was essentially the same, but may
be I missed something. I will take a look.

"Flip" wrote:
Howdy. I believe I got it to work properly (as you expected) for me.
Here's the code I used (slightly modified to get it to compile). Output at
the end.
//--------------------------------------------------------------start code
using System;

public class Base
{
}

public class Derived : Base
{
}

public class Service
{
public void Send(Base baseObject)
{
// send baseObject
Console.WriteLine("Called public void Send(Base baseObject) signature");
}

public void Send(Derived derivedObject)
{
// send derivedObject
Console.WriteLine("Called public void Send(Subclass derivedObject)
signature");
}
}

public class MainClass
{
public static void Main(string[] args)
{
Base baseObject = new Base();
Derived derivedObject = new Derived();

Service service = new Service();

// this calls public void Send(Base baseObject) as expected
service.Send(baseObject);

// this calls public void Send(Base baseObject),
// but it should call public void Send(Subclass derivedObject),
// shouldn't it???
service.Send(derivedObject);
}
}
//--------------------------------------------------------------end code
And here's the output I see.

C:\temp>basetesting
Called public void Send(Base baseObject) signature
Called public void Send(Subclass derivedObject) signature

C:\temp>

Nov 17 '05 #7
The signature with Subclass should be with Derived, sorry.

"Joe Mayo" wrote:
Hi Dave,

Service doesn't have an overload with a Derived parameter, so the compiler
used a best match that took the overload with the Base parameter. From the
information you've given, I can't tell what SubClass is. However, if you
change the definition of Send(SubClass derivedObject) to this, you could get
what you expect:

public void Send(Derived derivedObject)
{
// send derivedObject
Console.Out.WriteLine("Called public void Send(Derived derivedObject)
signature");
}

Joe
--
http://www.csharp-station.com

"Dave Raskin" <Dave Ra****@discussions.microsoft.com> wrote in message
news:0A**********************************@microsof t.com...
public class Base
{
}

public class Derived : Base
{
}

public class Service
{
public void Send(Base baseObject)
{
// send baseObject
Console.Out.WriteLine("Called public void Send(Base baseObject)
signature");
}

public void Send(Subclass derivedObject)
{
// send derivedObject
Console.Out.WriteLine("Called public void Send(Subclass derivedObject)
signature");
}
}

public class MainClass
{
public static void Main(string[] args)
{
Base baseObject = new Base();
Derived derivedObject = new Derived();

Service service = new Service();

// this calls public void Send(Base baseObject) as expected
service.Send(baseObject);

// this calls public void Send(Base baseObject),
// but it should call public void Send(Subclass derivedObject),
// shouldn't it???
service.Send(derivedObject);
}
}

I expect this to work, but I tested it at runtime, verifying that the
instance is of the Derived class and it still calls the signature with the
base class.

thanks,

Dave Raskin


Nov 17 '05 #8
The signature with Subclass should be with Derived, sorry.

"Joe Mayo" wrote:
Hi Dave,

Service doesn't have an overload with a Derived parameter, so the compiler
used a best match that took the overload with the Base parameter. From the
information you've given, I can't tell what SubClass is. However, if you
change the definition of Send(SubClass derivedObject) to this, you could get
what you expect:

public void Send(Derived derivedObject)
{
// send derivedObject
Console.Out.WriteLine("Called public void Send(Derived derivedObject)
signature");
}

Joe
--
http://www.csharp-station.com

"Dave Raskin" <Dave Ra****@discussions.microsoft.com> wrote in message
news:0A**********************************@microsof t.com...
public class Base
{
}

public class Derived : Base
{
}

public class Service
{
public void Send(Base baseObject)
{
// send baseObject
Console.Out.WriteLine("Called public void Send(Base baseObject)
signature");
}

public void Send(Subclass derivedObject)
{
// send derivedObject
Console.Out.WriteLine("Called public void Send(Subclass derivedObject)
signature");
}
}

public class MainClass
{
public static void Main(string[] args)
{
Base baseObject = new Base();
Derived derivedObject = new Derived();

Service service = new Service();

// this calls public void Send(Base baseObject) as expected
service.Send(baseObject);

// this calls public void Send(Base baseObject),
// but it should call public void Send(Subclass derivedObject),
// shouldn't it???
service.Send(derivedObject);
}
}

I expect this to work, but I tested it at runtime, verifying that the
instance is of the Derived class and it still calls the signature with the
base class.

thanks,

Dave Raskin


Nov 17 '05 #9
Ok, here's an example of where it fails. This has an added wrinkle of another
virtual method - Process().

public abstract class Base
{
protected Service service = new Service();

public abstract void Process();
}

public class BaseDerived : Base
{
public override void Process()
{
this.service.Send(this);
}
}

public class DerivedDerived : BaseDerived
{
}

public class Service
{
public void Send(Base baseObject)
{
// send baseObject
Console.Out.WriteLine("Called public void Send(Base baseObject)
signature");
}

public void Send(DerivedDerived derivedObject)
{
// send derivedObject
Console.Out.WriteLine("Called public void Send(DerivedDerived
derivedObject) signature");
}
}

public class MainClass
{
public static void Main(string[] args)
{
BaseDerived baseObject = new BaseDerived();
DerivedDerived derivedObject = new DerivedDerived();

Service service = new Service();

// this calls public void Send(Base baseObject) as expected
baseObject.Process();

// this calls public void Send(Base baseObject),
// but it should call public void Send(Subclass derivedObject),
// shouldn't it???
derivedObject.Process();
}
}
Nov 17 '05 #10
Ok, here's an example of where it fails. This has an added wrinkle of another
virtual method - Process().

public abstract class Base
{
protected Service service = new Service();

public abstract void Process();
}

public class BaseDerived : Base
{
public override void Process()
{
this.service.Send(this);
}
}

public class DerivedDerived : BaseDerived
{
}

public class Service
{
public void Send(Base baseObject)
{
// send baseObject
Console.Out.WriteLine("Called public void Send(Base baseObject)
signature");
}

public void Send(DerivedDerived derivedObject)
{
// send derivedObject
Console.Out.WriteLine("Called public void Send(DerivedDerived
derivedObject) signature");
}
}

public class MainClass
{
public static void Main(string[] args)
{
BaseDerived baseObject = new BaseDerived();
DerivedDerived derivedObject = new DerivedDerived();

Service service = new Service();

// this calls public void Send(Base baseObject) as expected
baseObject.Process();

// this calls public void Send(Base baseObject),
// but it should call public void Send(Subclass derivedObject),
// shouldn't it???
derivedObject.Process();
}
}
Nov 17 '05 #11
Dave Raskin <Da********@discussions.microsoft.com> wrote:
Ok, here's an example of where it fails. This has an added wrinkle of another
virtual method - Process().


<snip>

Overload resolution is done at compile time - it works out the
*signature* of which method will be called. Now, the Process method is
calling

this.service.Send(this)

and all it knows about "this" is that it's a BaseDerived - so it
doesn't know it can call Send(DerivedDerived).

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #12
Dave Raskin <Da********@discussions.microsoft.com> wrote:
Ok, here's an example of where it fails. This has an added wrinkle of another
virtual method - Process().


<snip>

Overload resolution is done at compile time - it works out the
*signature* of which method will be called. Now, the Process method is
calling

this.service.Send(this)

and all it knows about "this" is that it's a BaseDerived - so it
doesn't know it can call Send(DerivedDerived).

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 17 '05 #13
Jon is right.

Here's a simpler method to demonstrate the same phenomenon:

public class Base { ... }
public class Derived : Base { ... }
public class Main
{
private void Print(Base b) { Console.Writeline("Base"); }
private void Print(Derived d) { Console.Writeline("Derived"); }

public static void Main(string[] argv)
{
Derived d = new Derived();
Print(d); // Prints "Derived"
Print((Base)d); // Prints "Base", even though d is an instance
of Derived
}
}

Nov 17 '05 #14
Hmm, ok. is true in Java as well? It still seems like it should resolve it at
runtime, but I am not a compiler guy, so what do I know?

Thanks for the clarification!

daver

"Jon Skeet [C# MVP]" wrote:
Dave Raskin <Da********@discussions.microsoft.com> wrote:
Ok, here's an example of where it fails. This has an added wrinkle of another
virtual method - Process().


<snip>

Overload resolution is done at compile time - it works out the
*signature* of which method will be called. Now, the Process method is
calling

this.service.Send(this)

and all it knows about "this" is that it's a BaseDerived - so it
doesn't know it can call Send(DerivedDerived).

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too

Nov 17 '05 #15
Bruce,

This seems like a flip of my example. Here you have a Derived type at
compile time and explicitely casting to the Base type. In my case, at compile
time it only knows about the Base type.

daver

"Bruce Wood" wrote:
Jon is right.

Here's a simpler method to demonstrate the same phenomenon:

public class Base { ... }
public class Derived : Base { ... }
public class Main
{
private void Print(Base b) { Console.Writeline("Base"); }
private void Print(Derived d) { Console.Writeline("Derived"); }

public static void Main(string[] argv)
{
Derived d = new Derived();
Print(d); // Prints "Derived"
Print((Base)d); // Prints "Base", even though d is an instance
of Derived
}
}

Nov 17 '05 #16
Yes, but it illustrates the same thing: the run-time type of the
instantiated object isn't what determines which method signature to
call. The compiler decides which method signature to invoke.

Nov 17 '05 #17
Yes, Java is the same. I believe that C++ is also the same.

The rule goes liket his:

The method signature is determined at compile time. That is, if a
method has several different versions with different parameter lists,
the compile-type type of the value passed to the method determines the
signature chosen.

The method overload is determined at run time. That is, if a particular
signature of a particular method is overloaded in a child class, then
whether the base class method or the child class method is to be called
is determined at run time.

(So, just because the compiler determines the signature to call,
_doesn't_ mean that it has decided whether to call the base or derived
implementation of that method. If the derived class overloads the
method, then the choice between the two methods is made at run time.

Nov 17 '05 #18
Rats. I screwed up the use of the term "overload" again. :(

Overload resolution is done at compile time: "overload" refers to
methods with the same name but different signatures.

Override resolution is done at run time: "override" refers to methods
with the same name and the same signature defined at different levels
of the class hierarchy.

Nov 17 '05 #19
Right, got it, makes sense now. I was wrong all this time, go figure ;-)

daver

"Bruce Wood" wrote:
Rats. I screwed up the use of the term "overload" again. :(

Overload resolution is done at compile time: "overload" refers to
methods with the same name but different signatures.

Override resolution is done at run time: "override" refers to methods
with the same name and the same signature defined at different levels
of the class hierarchy.

Nov 17 '05 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

11
by: JohnR | last post by:
I'm trying to find a way to create a variable of a given type at runtime where I won't know the type until it actually executes. For example, dim x as object = "hi" x is declared as an object...
1
by: Joe HM | last post by:
Hello - I have two Enums for which I would like to define type conversions ... Public Enum eA A2 = 0 A2 = 1 End Enum Public Enum eB B1 = 2
4
by: Charles Churchill | last post by:
I apologize if this question has been asked before, but after about half an hour of searching I haven't been able to find an answer online. My code is beloiw, with comments pertaining to my...
4
by: Random | last post by:
I want to define a generics method so the user can determine what type they expect returned from the method. By examining the generics argument, I would determine the operation that needs to be...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.