473,386 Members | 1,799 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,386 software developers and data experts.

Confused by overloading (or can I claim it's a compiler bug...?)

AJ
Why does the following behave as it does...?

public class Base
{
public void Add( byte b )
{
}
}

public class TestClass : Base
{
public void Add( int s )
{
byte x = 0;
Add( x );
}
}

then call with
new TestClass().Add( 10 );

-The Add(int) override gets called (good). Which in turn class the
___Add(int)___ override.

Why doesn't this second call hit the base class's Add( byte ) ??

[It works as I'd expected if the Add(byte) method is defined in
TestClass rather than Base, or you call base.Add(x) ]
Mar 26 '07 #1
15 1278
On Mar 26, 11:05 am, AJ <n...@nowhere.comwrote:
Why does the following behave as it does...?

public class Base
{
public void Add( byte b )
{
}
}

public class TestClass : Base
{
public void Add( int s )
{
byte x = 0;
Add( x );
}
}

then call with
new TestClass().Add( 10 );

-The Add(int) override gets called (good). Which in turn class the
___Add(int)___ override.

Why doesn't this second call hit the base class's Add( byte ) ??

[It works as I'd expected if the Add(byte) method is defined in
TestClass rather than Base, or you call base.Add(x) ]
Look at your compiler errors; you should be getting a warning that
TestClass is hiding a member of the base class. You need to add the
virtual keyword to the method definition in the base class, then add
the overrides keyword to the method definition in the subclass. If
you need to call the base, you need to do so yourself.

Mar 26 '07 #2
That's not correct. There is no hiding here.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"Andy" <an***@med-associates.comwrote in message
news:11*********************@y80g2000hsf.googlegro ups.com...
On Mar 26, 11:05 am, AJ <n...@nowhere.comwrote:
>Why does the following behave as it does...?

public class Base
{
public void Add( byte b )
{
}
}

public class TestClass : Base
{
public void Add( int s )
{
byte x = 0;
Add( x );
}
}

then call with
new TestClass().Add( 10 );

-The Add(int) override gets called (good). Which in turn class the
___Add(int)___ override.

Why doesn't this second call hit the base class's Add( byte ) ??

[It works as I'd expected if the Add(byte) method is defined in
TestClass rather than Base, or you call base.Add(x) ]

Look at your compiler errors; you should be getting a warning that
TestClass is hiding a member of the base class. You need to add the
virtual keyword to the method definition in the base class, then add
the overrides keyword to the method definition in the subclass. If
you need to call the base, you need to do so yourself.

Mar 26 '07 #3
AJ
In article <11*********************@y80g2000hsf.googlegroups. com>,
an***@med-associates.com says...
On Mar 26, 11:05 am, AJ <n...@nowhere.comwrote:
Why does the following behave as it does...?

public class Base
{
public void Add( byte b )
{
}
}

public class TestClass : Base
{
public void Add( int s )
{
byte x = 0;
Add( x );
}
}

then call with
new TestClass().Add( 10 );

-The Add(int) override gets called (good). Which in turn class the
___Add(int)___ override.

Why doesn't this second call hit the base class's Add( byte ) ??

[It works as I'd expected if the Add(byte) method is defined in
TestClass rather than Base, or you call base.Add(x) ]

Look at your compiler errors; you should be getting a warning that
TestClass is hiding a member of the base class. You need to add the
virtual keyword to the method definition in the base class, then add
the overrides keyword to the method definition in the subclass. If
you need to call the base, you need to do so yourself.

I'm overloading, not overriding..

Mar 26 '07 #4
On Mar 26, 4:05 pm, AJ <n...@nowhere.comwrote:

<snip>
-The Add(int) override gets called (good). Which in turn class the
___Add(int)___ override.

Why doesn't this second call hit the base class's Add( byte ) ??
<snip>

Because the spec is very, very weird when it comes to overloading.
>From memory, when it tries to work out which overload to take, if
there are *any* valid signatures (i.e. ones which can match with
implicit conversion) in a more derived class than a less derived
class, all signatures in the less derived class are effectively
removed.

What's even weirder is that this includes signatures which are
overridden in the derived class:
using System;

class Base
{
public virtual void Foo(string x)
{
Console.WriteLine ("Base.Foo(string)");
}
}

class Derived : Base
{
public override void Foo(string x)
{
Console.WriteLine ("Derived.Foo(string)");
}

public void Foo(object x)
{
Console.WriteLine ("Derived.Foo(object)");
}
}

class Test
{
static void Main()
{
new Derived().Foo("Hello");
}
}

The output, contrary to intuitive expectations, is
"Derived.Foo(object)".

It's bonkers if you ask me, but that's what the spec says...

Jon

Mar 26 '07 #5
AJ
In article <11**********************@p77g2000hsh.googlegroups .com>,
sk***@pobox.com says...
On Mar 26, 4:05 pm, AJ <n...@nowhere.comwrote:

<snip>
-The Add(int) override gets called (good). Which in turn class the
___Add(int)___ override.

Why doesn't this second call hit the base class's Add( byte ) ??

<snip>

Because the spec is very, very weird when it comes to overloading.
From memory, when it tries to work out which overload to take, if
there are *any* valid signatures (i.e. ones which can match with
implicit conversion) in a more derived class than a less derived
class, all signatures in the less derived class are effectively
removed.

What's even weirder is that this includes signatures which are
overridden in the derived class:
That's nasty..... So, if my original example started as a single class,
then I refactor to create the base class (without changing anything
else), I suddenly get different behaviour (because the Add(byte) is no
longer being called.)

Ugh. Ugh. Ugh.

Mar 26 '07 #6
On Mar 26, 4:55 pm, AJ <n...@nowhere.comwrote:
What's even weirder is that this includes signatures which are
overridden in the derived class:

That's nasty..... So, if my original example started as a single class,
then I refactor to create the base class (without changing anything
else), I suddenly get different behaviour (because the Add(byte) is no
longer being called.)

Ugh. Ugh. Ugh.
Absolutely. I believe this to be unintentional. When I contacted a
couple of members of the ECMA committee, they were somewhat horrified
too :)

Jon

Mar 26 '07 #7
AJ
In article <11**********************@n76g2000hsh.googlegroups .com>,
sk***@pobox.com says...
On Mar 26, 4:55 pm, AJ <n...@nowhere.comwrote:
What's even weirder is that this includes signatures which are
overridden in the derived class:
That's nasty..... So, if my original example started as a single class,
then I refactor to create the base class (without changing anything
else), I suddenly get different behaviour (because the Add(byte) is no
longer being called.)

Ugh. Ugh. Ugh.

Absolutely. I believe this to be unintentional. When I contacted a
couple of members of the ECMA committee, they were somewhat horrified
too :)
Do you mean an unintentional sideeffect of the rules, or an unitentional
'feature' in the compiler?

I've just briefly downloaded and looked at "ECMA-334 C# Language
specification 4th Edition/ June 2006"

I can see rules about deciding which overloaded function to use (sect.
14.4.2) , but can't see any mention that inheritance comes into the
decision..

Mar 26 '07 #8
VJ
This really explains a problem we had in the last 2 days, and I was finally
going to post. This helps..! Thanks Jon.. AJ...

VJ
"Jon Skeet [C# MVP]" <sk***@pobox.comwrote in message
news:11**********************@p77g2000hsh.googlegr oups.com...
On Mar 26, 4:05 pm, AJ <n...@nowhere.comwrote:

<snip>
>-The Add(int) override gets called (good). Which in turn class the
___Add(int)___ override.

Why doesn't this second call hit the base class's Add( byte ) ??

<snip>

Because the spec is very, very weird when it comes to overloading.
>>From memory, when it tries to work out which overload to take, if
there are *any* valid signatures (i.e. ones which can match with
implicit conversion) in a more derived class than a less derived
class, all signatures in the less derived class are effectively
removed.

What's even weirder is that this includes signatures which are
overridden in the derived class:
using System;

class Base
{
public virtual void Foo(string x)
{
Console.WriteLine ("Base.Foo(string)");
}
}

class Derived : Base
{
public override void Foo(string x)
{
Console.WriteLine ("Derived.Foo(string)");
}

public void Foo(object x)
{
Console.WriteLine ("Derived.Foo(object)");
}
}

class Test
{
static void Main()
{
new Derived().Foo("Hello");
}
}

The output, contrary to intuitive expectations, is
"Derived.Foo(object)".

It's bonkers if you ask me, but that's what the spec says...

Jon

Mar 26 '07 #9
AJ <no***@nowhere.comwrote:
Absolutely. I believe this to be unintentional. When I contacted a
couple of members of the ECMA committee, they were somewhat horrified
too :)

Do you mean an unintentional sideeffect of the rules, or an unitentional
'feature' in the compiler?
Unintentional side-effect of the rules. The compiler obeys the spec
here.
I've just briefly downloaded and looked at "ECMA-334 C# Language
specification 4th Edition/ June 2006"

I can see rules about deciding which overloaded function to use (sect.
14.4.2) , but can't see any mention that inheritance comes into the
decision..
It's in 14.5.5.1:

<quote>
The set of candidate methods is reduced to contain only methods from
the most derived types: For each method C.F in the set, where C is the
type in which the method F is declared, all methods declared in a
base type of C are removed from the set.
</quote>

(An overriding method doesn't count as a declaration - the declaration
is in the base class.)

It's not the easiest spec in the world to navigate, unfortunately.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 26 '07 #10
Jon Skeet [C# MVP] wrote:
Because the spec is very, very weird when it comes to overloading.
It's actually with good reason: it makes it safe to add new overloads to
base classes in the framework without worrying that existing programs
are going to break when recompiled, due to finding the new overload when
the new framework is released.
It's bonkers if you ask me, but that's what the spec says...
AndersH actually appears to be very proud of this feature of C#, I
recall watching a video where he pointed out that he wasn't aware of any
other language that did overloading this way.

-- Barry

--
http://barrkel.blogspot.com/
Mar 27 '07 #11
Jon Skeet [C# MVP] wrote:
The output, contrary to intuitive expectations, is
"Derived.Foo(object)".

It's bonkers if you ask me, but that's what the spec says...
Whups - I do agree with you about the overridden version though, it
shouldn't remove overridden overloads, as that's evidence that the
descendant is aware of the ancestor's method.

-- Barry

--
http://barrkel.blogspot.com/
Mar 27 '07 #12
Barry Kelly <ba***********@gmail.comwrote:
Jon Skeet [C# MVP] wrote:
Because the spec is very, very weird when it comes to overloading.

It's actually with good reason: it makes it safe to add new overloads to
base classes in the framework without worrying that existing programs
are going to break when recompiled, due to finding the new overload when
the new framework is released.
That's a reasonable point - but I still find it counterintuitive, and
it seems that others do too.
It's bonkers if you ask me, but that's what the spec says...

AndersH actually appears to be very proud of this feature of C#, I
recall watching a video where he pointed out that he wasn't aware of any
other language that did overloading this way.
I don't see that as an advantage - I see it as a positive disadvantage.
It means that everyone has to read the specification in considerable
detail in order to be able to predict what their code will do.

Not only have I never found anyone who would intuitively expect the
current behaviour - I haven't found anyone who worked out why it was on
their first trawl through the spec, either. It always takes a very
careful analysis to find out what should actually happen. (It took me
ages first time.)

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too
Mar 27 '07 #13
On Tue, 27 Mar 2007 07:29:38 +0100, Jon Skeet [C# MVP]
<sk***@pobox.comwrote:
>I don't see that as an advantage - I see it as a positive disadvantage.
It means that everyone has to read the specification in considerable
detail in order to be able to predict what their code will do.
I would agree, but framework versioning is apparently the highest
priority for the CLR team. I once submitted a similar request to
change the overload resolution of generic methods (non-generic base
class methods are ignored if a matching generic derived method is
found), and I got the same reply:

https://connect.microsoft.com/Visual...edbackID=92075

"The reason we 'stop the search' in the current type is because of
versioning. If we didn't, then it would be possible for someone to add
a method in the base class and suddenly the code that was behaving one
way, will start to do something different because the new method will
be called. This is a variant of the fragile base class problem."
--
http://www.kynosarges.de
Mar 27 '07 #14
AJ
In article <MP************************@msnews.microsoft.com >,
sk***@pobox.com says...
Barry Kelly <ba***********@gmail.comwrote:
Jon Skeet [C# MVP] wrote:
Because the spec is very, very weird when it comes to overloading.
It's actually with good reason: it makes it safe to add new overloads to
base classes in the framework without worrying that existing programs
are going to break when recompiled, due to finding the new overload when
the new framework is released.

That's a reasonable point - but I still find it counterintuitive, and
it seems that others do too.
I'm still not convinced that it's the 'right' decision, nor that the
spec really explains it that well (if at all..)

However, if you're all suggesting that the behaviour is correct, then
the IDE has a bug - the intellisense displays the two overloads as
options where, in my example, I don't think that the Add(byte) method is
_ever_ going to get called, since the byte will always get promoted to
an int..
Mar 27 '07 #15

"Barry Kelly" <ba***********@gmail.comwrote in message
news:jj********************************@4ax.com...
Jon Skeet [C# MVP] wrote:
>The output, contrary to intuitive expectations, is
"Derived.Foo(object)".

It's bonkers if you ask me, but that's what the spec says...

Whups - I do agree with you about the overridden version though, it
shouldn't remove overridden overloads, as that's evidence that the
descendant is aware of the ancestor's method.
And as nearly as I can tell, that's how C++ works -- you can't overload a
base member function, you end up overriding, but your own overrides of base
functions are also considered.
Mar 30 '07 #16

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

Similar topics

39
by: zeus | last post by:
I know function overloading is not supported in C. I have a few questions about this: 1. Why? is it from technical reasons? if so, which? 2. why wasn't it introduced to the ANSI? 3. Is there any...
45
by: JaSeong Ju | last post by:
I would like to overload a C function. Is there any easy way to do this?
31
by: | last post by:
Hi, Why can I not overload on just the return type? Say for example. public int blah(int x) { }
1
by: Ramsey Schaffnit | last post by:
Documentation for error message Compiler Error CS0163 says: Control cannot fall through from one case label ('label') to another Ok, fine. Documentation for switch statement says the same...
6
by: Viktar Zhardzetski | last post by:
Hi everybody, let me start with a simple sample to replicate the problem: 1. Create a new Windows Application C# project with 2 forms - MainForm and FaultyForm; 2. In the faulty form...
3
by: khoda | last post by:
i'm getting a little confused with some terminology. it's hard to get all of these questions answered through google. please correct me if i make any mistakes in my assumptions when asking the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
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
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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
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...

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.