Reputation: 4750
I just stumbled across something in VB.NET that looks like it shouldn't be able to compile:
Private Structure SomeStruct
Friend ReadOnly Property Text1 As String
Friend ReadOnly Property Text2 As String
Friend ReadOnly Property Text3 As String
Friend Sub New(text2 As String, Optional text3 As String = Nothing)
Me.New(Nothing, text2, text3)
End Sub
Friend Sub New(text1 As String, text2 As String, Optional text3 As String = Nothing)
Me.Text1 = text1
Me.Text2 = text2
Me.Text3 = text3
End Sub
End Structure
Not only is the above able to compile, but this is also able to compile in outside code:
Dim structs As SomeStruct() = {New SomeStruct("Argument1", "Argument2")}
In the line above, it seems ambiguous as to which constructor those two strings go. This shouldn't be possible - especially the one line above that's actually calling a constructor from outside of the structure - but it compiles just fine. (I'm using VS2015 and .NET 4.5.)
Any decent compiler that allows this would be consistent in which constructor it would map the two string arguments from the outside code to, but why would this be allowed in the first place? Is this a gap in the language's definition that leaves different compilers to their own discretion (the sort of thing that stuff like .NET and Java are supposed to be good about not having)? Is this in the language by design? Is there a consistent rule that Microsoft has chosen, or is this just a simple bug?
What is the explanation for this?
Upvotes: 3
Views: 45
Reputation: 9089
Looks like VB attempts to match the number of arguments first as it does call the 2 parameter constructor.
Even though I guess you could say they are ambiguous, there is a way to call the 2nd constructor by leaving the third parameter blank.
New SomeStruct("foo", "bar",) 'Notice the extra comma.
I don't like the idea that this is allowed, but to me this is more of a VB gotcha since there are ways to call the desired constructor.
Upvotes: 2