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

Constructor Overloading Bug?

P: n/a
Hi,

does anybody know, why the second contructor isn't called in this example?
Are you able to reproduce this bug?
Thanks

Klaus

Public Class Something

Shared Sub Main()
Dim test1 As New Something("C"c, 1)
Dim test2 As New Something("String", 2)
End Sub

Sub New(ByVal aChar As Char, ByVal aByte As Byte)
Console.WriteLine("Char/Byte-Konstruktor")
End Sub

Sub New(ByVal aString As String, ByVal anInteger As Integer)
Console.WriteLine("String/Integer-Konstruktor")
End Sub

End Class
Nov 20 '05 #1
Share this Question
Share on Google+
14 Replies


P: n/a
....actually, it is the first constructor, that is not being called...

Klaus

"Klaus Löffelmann" <fo***********@loeffelmann.de> schrieb im Newsbeitrag
news:40***********************@news.freenet.de...
Hi,

does anybody know, why the second contructor isn't called in this example?
Are you able to reproduce this bug?
Thanks

Klaus

Public Class Something

Shared Sub Main()
Dim test1 As New Something("C"c, 1)
Dim test2 As New Something("String", 2)
End Sub

Sub New(ByVal aChar As Char, ByVal aByte As Byte)
Console.WriteLine("Char/Byte-Konstruktor")
End Sub

Sub New(ByVal aString As String, ByVal anInteger As Integer)
Console.WriteLine("String/Integer-Konstruktor")
End Sub

End Class

Nov 20 '05 #2

P: n/a
Klaus,
does anybody know, why the second contructor isn't called in this example?
Are you able to reproduce this bug?

If you force the constant 1 to be a Byte (it's an Integer by default),
the first constructor will be called.

Dim test1 As New Something("C"c, CByte(1))

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 20 '05 #3

P: n/a
Cor
Hi Klaus,

I do not know what is it theoretical, but this he does well,
Dim test1 As New Something("C"c, CByte(1))

Just if it first trys to resolve to find if it is an integer and than
threats the character as a one position string.

I hope this helps something.

Cor
does anybody know, why the second contructor isn't called in this example?
Are you able to reproduce this bug?
Thanks

Nov 20 '05 #4

P: n/a
Mattias,

why do I have to force the second parameter to be a byte, when it's already
clear that I'm pushing a char, to begin with. I mean, if you declare a
"normal" procedure to take a char and you then try to give it a string, the
compiler is complaining. So why can't he then tell the difference in this
example?

Aside of that: I tried what you suggested in my project already (this is
just an excerpt), and of course converted the second parameter to a byte. It
called the string/Integer constructor, anyway. Only after I changed the
order, I got it to work. But the curious thing is: When I rechanged the
order, it suddenly could recognize the byte as a byte, and now I can't
reproduce the behaviour anymore.

However, the behaviour described in this exceprt is weird enough, isn't it?

Klaus

"Mattias Sjögren" <ma********************@mvps.org> schrieb im Newsbeitrag
news:er**************@TK2MSFTNGP12.phx.gbl...
Klaus,
does anybody know, why the second contructor isn't called in this example?Are you able to reproduce this bug?

If you force the constant 1 to be a Byte (it's an Integer by default),
the first constructor will be called.

Dim test1 As New Something("C"c, CByte(1))

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Nov 20 '05 #5

P: n/a
Klaus,
Dim test1 As New Something("C"c, 1) 1 is an Integer literal, Char can be upgraded to a string, but an Integer
cannot be downgraded to a Byte, hence the second constructor is called.

I don't see how to specify a Byte literal itself, so try:
Dim test1 As New Something("C"c, CByte(1))
Alternatively add a third constructor (or change the first constructor),
such as: Sub New(ByVal aChar As Char, ByVal anInteger As Integer)
Console.WriteLine("Char/Integer-Konstruktor")
End Sub
I would probably simply define two constructors Char/Integer &
String/Integer constructors to "avoid" the problem...

Hope this helps
Jay

"Klaus Löffelmann" <fo***********@loeffelmann.de> wrote in message
news:40***********************@news.freenet.de... Hi,

does anybody know, why the second contructor isn't called in this example?
Are you able to reproduce this bug?
Thanks

Klaus

Public Class Something

Shared Sub Main()
Dim test1 As New Something("C"c, 1)
Dim test2 As New Something("String", 2)
End Sub

Sub New(ByVal aChar As Char, ByVal aByte As Byte)
Console.WriteLine("Char/Byte-Konstruktor")
End Sub

Sub New(ByVal aString As String, ByVal anInteger As Integer)
Console.WriteLine("String/Integer-Konstruktor")
End Sub

End Class

Nov 20 '05 #6

P: n/a
Klaus,
What do you mean "changed the order"?

Do you mean you made the String/Integer come before the Char/Byte in the
source?

Or that you had Integer/String & Byte/Char constructors?

As I stated in my other post, the 1 is being treated as an Integer Literal
first, VB.NET knows it can convert the Char to a string, hence it is picking
the String/Integer overload!

Is this a bug, possible! is this "by design", possible! I know enough about
implementing overloading in a compiler to understand it can be very
difficult to get overload resolution to work.

Here are a number of articles on VB.NET overload method resolution:
http://msdn.microsoft.com/library/de...bspec9_3_4.asp

http://msdn.microsoft.com/library/de...procedures.asp

Mostly this one:
http://msdn.microsoft.com/library/de...resolution.asp

I would say it is seeing the 1 as an integer, and according to rule 2 on the
last link is throwing away the Char/Byte overload.

Hope this helps
Jay

"Klaus Löffelmann" <fo***********@loeffelmann.de> wrote in message
news:40***********************@news.freenet.de...
Mattias,

why do I have to force the second parameter to be a byte, when it's already clear that I'm pushing a char, to begin with. I mean, if you declare a
"normal" procedure to take a char and you then try to give it a string, the compiler is complaining. So why can't he then tell the difference in this
example?

Aside of that: I tried what you suggested in my project already (this is
just an excerpt), and of course converted the second parameter to a byte. It called the string/Integer constructor, anyway. Only after I changed the
order, I got it to work. But the curious thing is: When I rechanged the
order, it suddenly could recognize the byte as a byte, and now I can't
reproduce the behaviour anymore.

However, the behaviour described in this exceprt is weird enough, isn't it?
Klaus

"Mattias Sjögren" <ma********************@mvps.org> schrieb im Newsbeitrag
news:er**************@TK2MSFTNGP12.phx.gbl...
Klaus,
does anybody know, why the second contructor isn't called in this example?Are you able to reproduce this bug?

If you force the constant 1 to be a Byte (it's an Integer by default),
the first constructor will be called.

Dim test1 As New Something("C"c, CByte(1))

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.


Nov 20 '05 #7

P: n/a
Nope,

I was wrong. Chars get promoted to Strings, when VB feels to do so. That was
my mistake.
But consistently, overloaded procedures only differing in char and string
shouldn't be allowed then, anyway.

Thanks, everybody

Klaus
"Klaus Löffelmann" <fo***********@loeffelmann.de> schrieb im Newsbeitrag
news:40***********************@news.freenet.de...
Mattias,

why do I have to force the second parameter to be a byte, when it's already clear that I'm pushing a char, to begin with. I mean, if you declare a
"normal" procedure to take a char and you then try to give it a string, the compiler is complaining. So why can't he then tell the difference in this
example?

Aside of that: I tried what you suggested in my project already (this is
just an excerpt), and of course converted the second parameter to a byte. It called the string/Integer constructor, anyway. Only after I changed the
order, I got it to work. But the curious thing is: When I rechanged the
order, it suddenly could recognize the byte as a byte, and now I can't
reproduce the behaviour anymore.

However, the behaviour described in this exceprt is weird enough, isn't it?
Klaus

"Mattias Sjögren" <ma********************@mvps.org> schrieb im Newsbeitrag
news:er**************@TK2MSFTNGP12.phx.gbl...
Klaus,
does anybody know, why the second contructor isn't called in this example?Are you able to reproduce this bug?

If you force the constant 1 to be a Byte (it's an Integer by default),
the first constructor will be called.

Dim test1 As New Something("C"c, CByte(1))

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.


Nov 20 '05 #8

P: n/a
Jay,

Sorry, I replied and then read you message - I was out of sync, so to say.
The Integer and Byte stuff was totally clear to me; it's just, as I already
pointed out, that overloading procedures just with a different char and
string parameter shouldn't be allowed then, isn't it?

Thanks for your help,

Klaus

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> schrieb im
Newsbeitrag news:up**************@TK2MSFTNGP11.phx.gbl...
Klaus,
What do you mean "changed the order"?

Do you mean you made the String/Integer come before the Char/Byte in the
source?

Or that you had Integer/String & Byte/Char constructors?

As I stated in my other post, the 1 is being treated as an Integer Literal
first, VB.NET knows it can convert the Char to a string, hence it is picking the String/Integer overload!

Is this a bug, possible! is this "by design", possible! I know enough about implementing overloading in a compiler to understand it can be very
difficult to get overload resolution to work.

Here are a number of articles on VB.NET overload method resolution:
http://msdn.microsoft.com/library/de...bspec9_3_4.asp
http://msdn.microsoft.com/library/de...procedures.asp
Mostly this one:
http://msdn.microsoft.com/library/de...resolution.asp
I would say it is seeing the 1 as an integer, and according to rule 2 on the last link is throwing away the Char/Byte overload.

Hope this helps
Jay

"Klaus Löffelmann" <fo***********@loeffelmann.de> wrote in message
news:40***********************@news.freenet.de...
Mattias,

why do I have to force the second parameter to be a byte, when it's already
clear that I'm pushing a char, to begin with. I mean, if you declare a
"normal" procedure to take a char and you then try to give it a string,

the
compiler is complaining. So why can't he then tell the difference in this example?

Aside of that: I tried what you suggested in my project already (this is
just an excerpt), and of course converted the second parameter to a byte. It
called the string/Integer constructor, anyway. Only after I changed the
order, I got it to work. But the curious thing is: When I rechanged the
order, it suddenly could recognize the byte as a byte, and now I can't
reproduce the behaviour anymore.

However, the behaviour described in this exceprt is weird enough, isn't

it?

Klaus

"Mattias Sjögren" <ma********************@mvps.org> schrieb im

Newsbeitrag news:er**************@TK2MSFTNGP12.phx.gbl...
Klaus,

>does anybody know, why the second contructor isn't called in this

example?
>Are you able to reproduce this bug?
If you force the constant 1 to be a Byte (it's an Integer by default),
the first constructor will be called.

Dim test1 As New Something("C"c, CByte(1))

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.



Nov 20 '05 #9

P: n/a
"Klaus Löffelmann" <fo***********@loeffelmann.de> schrieb
...actually, it is the first constructor, that is not being
called...


Dim test1 As New Something("C"c, 1)

The number 1 is interpreted as integer, not as byte. That's why the second
constructor is called - the Char "C"c is converted to a String because
widening conversions are allowed. Calling the first constructor would be a
narrowing conversion.

Use
Dim test1 As New Something("C"c, CByte(1))
instead.
--
Armin

http://www.plig.net/nnq/nquote.html
http://www.netmeister.org/news/learn2quote.html
Nov 20 '05 #10

P: n/a
Klaus,
I was wrong. Chars get promoted to Strings, when VB feels to do so. That was
my mistake.
But consistently, overloaded procedures only differing in char and string
shouldn't be allowed then, anyway.


Why do you say that? Do you also think that

Sub Foo(i As Integer)

Sub Foo(i As Long)

should be disallowed, just because an Integer can implicitly promoted
to a Long?

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Nov 20 '05 #11

P: n/a

"Mattias Sjögren" <ma********************@mvps.org> schrieb im Newsbeitrag
news:%2***************@tk2msftngp13.phx.gbl...
Klaus,
I was wrong. Chars get promoted to Strings, when VB feels to do so. That wasmy mistake.
But consistently, overloaded procedures only differing in char and string
shouldn't be allowed then, anyway.
Why do you say that? Do you also think that

Sub Foo(i As Integer)

Sub Foo(i As Long)

should be disallowed, just because an Integer can implicitly promoted
to a Long?


Why would I say that? The overloading resolution works fine, here, it's
unquestionable.
I just wanted to say, that to my mind the BCL sets the priority wrong in the
given example. The Integer/byte decision is not clear, granted. But actually
there is no mistake about char. All I said was that I'd rather stick to the
obvious (Char is clear, let's have the second parameter a byte then) than to
just assume (let's consider the second one an integer...) the second *and*
the first parameter (...oh, but then we have to promote the first one to a
string).

Klaus

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Nov 20 '05 #12

P: n/a
Klaus,
The Integer and Byte stuff was totally clear to me; it's just, as I already pointed out, that overloading procedures just with a different char and
string parameter shouldn't be allowed then, isn't it? No!

Both Char & String are distinct types so you are allowed to overload them,
as are Byte & Integer you are also allowed to overload them. Look at all the
overloads for System.Console.Write, all "primitive" types are represented!

The "problem" with your example, is that you had a literal 1, which you
assumed was a Byte. The literal 1 is defined to be an Integer. As Armin
stated, narrowing the Integer to a Byte is "not allowed" (possible loss of
precision, the fact its a literal that fits apparently is not a
consideration) so that overload was ruled out. Which leaves the widening to
String to match the second overload the only path available.

You can add a suffix to your literals to explicitly state what the literal
is: Such as:

1S ' a short literal
1I ' an explicit integer literal
1L ' a long literal

1 ' an implicit integer literal

The "problem" that I see there is no suffix for Byte.

1B ' a byte literal?

Unfortunately B is not valid, there is no literal suffix for Byte. However!
Single, Double, and Decimal all have suffixes...

As others have pointed out you can use CByte to get the overload you want to
be selected. Also if you had the 1 in a Byte variable, the correct overload
would be called.

The short of it is: The Char/Byte overload cannot be matched with a literal
(for Byte), as there are no Byte literals!

Hope this helps
Jay
"Klaus Löffelmann" <fo***********@loeffelmann.de> wrote in message
news:40***********************@news.freenet.de... Jay,

Sorry, I replied and then read you message - I was out of sync, so to say.
The Integer and Byte stuff was totally clear to me; it's just, as I already pointed out, that overloading procedures just with a different char and
string parameter shouldn't be allowed then, isn't it?

Thanks for your help,

Klaus

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> schrieb im
Newsbeitrag news:up**************@TK2MSFTNGP11.phx.gbl...
Klaus,
What do you mean "changed the order"?

Do you mean you made the String/Integer come before the Char/Byte in the
source?

Or that you had Integer/String & Byte/Char constructors?

As I stated in my other post, the 1 is being treated as an Integer Literal
first, VB.NET knows it can convert the Char to a string, hence it is

picking
the String/Integer overload!

Is this a bug, possible! is this "by design", possible! I know enough

about
implementing overloading in a compiler to understand it can be very
difficult to get overload resolution to work.

Here are a number of articles on VB.NET overload method resolution:

http://msdn.microsoft.com/library/de...bspec9_3_4.asp

http://msdn.microsoft.com/library/de...procedures.asp

Mostly this one:

http://msdn.microsoft.com/library/de...resolution.asp

I would say it is seeing the 1 as an integer, and according to rule 2 on

the
last link is throwing away the Char/Byte overload.

Hope this helps
Jay

"Klaus Löffelmann" <fo***********@loeffelmann.de> wrote in message
news:40***********************@news.freenet.de...
Mattias,

why do I have to force the second parameter to be a byte, when it's

already
clear that I'm pushing a char, to begin with. I mean, if you declare a
"normal" procedure to take a char and you then try to give it a string,
the
compiler is complaining. So why can't he then tell the difference in this example?

Aside of that: I tried what you suggested in my project already (this
is just an excerpt), and of course converted the second parameter to a

byte.
It
called the string/Integer constructor, anyway. Only after I changed the order, I got it to work. But the curious thing is: When I rechanged the order, it suddenly could recognize the byte as a byte, and now I can't
reproduce the behaviour anymore.

However, the behaviour described in this exceprt is weird enough, isn't it?

Klaus

"Mattias Sjögren" <ma********************@mvps.org> schrieb im

Newsbeitrag news:er**************@TK2MSFTNGP12.phx.gbl...
> Klaus,
>
> >does anybody know, why the second contructor isn't called in this
example?
> >Are you able to reproduce this bug?
>
>
> If you force the constant 1 to be a Byte (it's an Integer by

default), > the first constructor will be called.
>
> Dim test1 As New Something("C"c, CByte(1))
>
>
>
> Mattias
>
> --
> Mattias Sjögren [MVP] mattias @ mvps.org
> http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
> Please reply only to the newsgroup.



Nov 20 '05 #13

P: n/a
Klaus,
I just wanted to say, that to my mind the BCL sets the priority wrong in the given example. The Integer/byte decision is not clear, granted. But actually there is no mistake about char. All I said was that I'd rather stick to the obvious (Char is clear, let's have the second parameter a byte then) than to just assume (let's consider the second one an integer...) the second *and*
the first parameter (...oh, but then we have to promote the first one to a
string). The BCL is not setting the priority here as much as VB.NET itself is setting
the priority here. Based on the rules that I gave links to earlier.

VB.NET is not assuming the second is an integer, the literal 1 is defined to
be an integer. As clearly stated in the following topic:

http://msdn.microsoft.com/library/de...bspec2_4_2.asp

Hence your sample is effectively:

Const c As Char = "C"c
Const i As Integer = 1

Dim test1 As New Something(c, i)

Seeing as the Integer cannot be squeezed into a Byte, while the Char can be
expanded into a String, the String/Integer overload is the one that is used!

Hope this helps
Jay
"Klaus Löffelmann" <fo***********@loeffelmann.de> wrote in message
news:40***********************@news.freenet.de...
"Mattias Sjögren" <ma********************@mvps.org> schrieb im Newsbeitrag
news:%2***************@tk2msftngp13.phx.gbl...
Klaus,
I was wrong. Chars get promoted to Strings, when VB feels to do so. That
was
my mistake.
But consistently, overloaded procedures only differing in char and
stringshouldn't be allowed then, anyway.


Why do you say that? Do you also think that

Sub Foo(i As Integer)

Sub Foo(i As Long)

should be disallowed, just because an Integer can implicitly promoted
to a Long?


Why would I say that? The overloading resolution works fine, here, it's
unquestionable.
I just wanted to say, that to my mind the BCL sets the priority wrong in

the given example. The Integer/byte decision is not clear, granted. But actually there is no mistake about char. All I said was that I'd rather stick to the obvious (Char is clear, let's have the second parameter a byte then) than to just assume (let's consider the second one an integer...) the second *and*
the first parameter (...oh, but then we have to promote the first one to a
string).

Klaus

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.


Nov 20 '05 #14

P: n/a
Yeah, you're right. I learned that the hard way.
It's already 0:00 here in Germany (OK, almost), maybe that's the reason I've
been so stubborn - actually, I'm not like that ;-)

Thanks for your help, I really appreciate it!

Klaus

"Jay B. Harlow [MVP - Outlook]" <Ja************@msn.com> schrieb im
Newsbeitrag news:%2****************@TK2MSFTNGP10.phx.gbl...
Klaus,
I just wanted to say, that to my mind the BCL sets the priority wrong in the
given example. The Integer/byte decision is not clear, granted. But

actually
there is no mistake about char. All I said was that I'd rather stick to

the
obvious (Char is clear, let's have the second parameter a byte then) than to
just assume (let's consider the second one an integer...) the second *and* the first parameter (...oh, but then we have to promote the first one to a string). The BCL is not setting the priority here as much as VB.NET itself is

setting the priority here. Based on the rules that I gave links to earlier.

VB.NET is not assuming the second is an integer, the literal 1 is defined to be an integer. As clearly stated in the following topic:

http://msdn.microsoft.com/library/de...bspec2_4_2.asp
Hence your sample is effectively:

Const c As Char = "C"c
Const i As Integer = 1

Dim test1 As New Something(c, i)

Seeing as the Integer cannot be squeezed into a Byte, while the Char can be expanded into a String, the String/Integer overload is the one that is used!
Hope this helps
Jay
"Klaus Löffelmann" <fo***********@loeffelmann.de> wrote in message
news:40***********************@news.freenet.de...

"Mattias Sjögren" <ma********************@mvps.org> schrieb im Newsbeitrag news:%2***************@tk2msftngp13.phx.gbl...
Klaus,

>I was wrong. Chars get promoted to Strings, when VB feels to do so. That
was
>my mistake.
>But consistently, overloaded procedures only differing in char and
string >shouldn't be allowed then, anyway.

Why do you say that? Do you also think that

Sub Foo(i As Integer)

Sub Foo(i As Long)

should be disallowed, just because an Integer can implicitly promoted
to a Long?


Why would I say that? The overloading resolution works fine, here, it's
unquestionable.
I just wanted to say, that to my mind the BCL sets the priority wrong in

the
given example. The Integer/byte decision is not clear, granted. But

actually
there is no mistake about char. All I said was that I'd rather stick to

the
obvious (Char is clear, let's have the second parameter a byte then)

than to
just assume (let's consider the second one an integer...) the second

*and* the first parameter (...oh, but then we have to promote the first one to a string).

Klaus

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.



Nov 20 '05 #15

This discussion thread is closed

Replies have been disabled for this discussion.