Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why won't this seemingly correct .NET code compile?

I'm asking in case I'm missing something obvious, but I think I may have stumbled upon a bug in .NET's compiler.

I have two projects in a .NET solution, one visual basic, one C#.

C# code, consisting of three overloaded static methods with default values:

public static class Class1 {      public static void TestFunc(int val1, int val2 = 0)     {     }      public static void TestFunc(int val1 = 0)     {     }      public static void TestFunc(string val1, int val2 = 0)     {      } } 

Visual basic code, calling one of the overloaded methods:

Option Explicit On Option Strict On Imports ClassLibrary1  Module Module1     Sub Main()         Dim x As Integer         Class1.TestFunc(x, 0)     End Sub End Module 

Compiling this code will fail, saying:

'TestFunc' is ambiguous because multiple kinds of members with this name exist in class 'ClassLibrary1.Class1'.

Why would it see this method as ambiguous? There is only one Class1.TestFunc with an (int, int) signature. Is this a bug, or am I missing something?

like image 514
w.brian Avatar asked Oct 25 '11 18:10

w.brian


2 Answers

Ultimately it appears to come down to how C# is implementing the optional parameters in your first static method. If you remove the default value on that, your solution should compile.

public static void TestFunc(int val1, int val2)  {  }  

Actually, in this case, I'm somewhat surprised that the C# compiles. You should either use optional parameters in C# or overloads, but not both. For example, how would you disambiguate the following:

public static void TestFunc(int val1, int val2 = 0)      {      }       public static void TestFunc(int val1)      {      }   

If I pass in the following, which of the two methods should be executed - the one with the optional parameter or the second without the second parameter?

TestFunc(1) 

A better solution if you want to include optional parameters in your C# implementation would be to combine the first and second methods and check your default value as necessary:

public static void TestFunc(int val1, int val2 = 0) { }  public static void TestFunc(string val1, int val2 = 0) { } 

Note, using this version, VB IS able to disambiguate which method to call.

like image 121
Jim Wooley Avatar answered Sep 19 '22 05:09

Jim Wooley


If you try to compile this in VB.NET you'll get

Sub TestFunc(ByVal val1 As Integer, Optional ByVal val2 As Integer = 0)  End Sub  Sub TestFunc(Optional ByVal val1 As Integer = 0)  End Sub 

you'll get Public Sub TestFunc(val1 As Integer, [val2 As Integer = 0])' and 'Public Sub TestFunc([val1 As Integer = 0])' cannot overload each other because they differ only by optional parameters.

so I'll say that VB.NET is more limited than C# in optional parameters overload.

like image 27
xanatos Avatar answered Sep 19 '22 05:09

xanatos