visual tag studio generar documentar documentacion codigo c# .net vb.net static-analysis

c# - tag - ¿Por qué no se compilará este código.NET aparentemente correcto?



generar documentacion visual studio 2017 (5)

Pregunto en caso de que me esté perdiendo algo obvio, pero creo que me he tropezado con un error en el compilador de .NET.

Tengo dos proyectos en una solución .NET, uno visual básico, un C #.

Código de C #, que consta de tres métodos estáticos sobrecargados con valores predeterminados:

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) { } }

Código básico visual, llamando a uno de los métodos sobrecargados:

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

La compilación de este código fallará, diciendo:

''TestFunc'' es ambiguo porque existen varios tipos de miembros con este nombre en la clase ''ClassLibrary1.Class1''.

¿Por qué vería este método como ambiguo? Solo hay un Class1.TestFunc con una firma (int, int). ¿Es esto un error, o me estoy perdiendo algo?


Editar

Cuando esta pregunta se publicó por primera vez:

Option Strict On

y

Option Explicit On

no se incluyeron en la pregunta por lo que esto cambia la respuesta de forma drástica.

Respuesta original antes de la edición de la pregunta

Porque esto:

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

Es ambiguo para:

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

VB.net puede convertir un entero en una cadena.


En última instancia, parece reducirse a cómo C # está implementando los parámetros opcionales en su primer método estático. Si elimina el valor predeterminado en eso, su solución debería compilarse.

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

De hecho, en este caso, estoy algo sorprendido de que compile C #. Debe usar parámetros opcionales en C # o sobrecargas, pero no en ambos. Por ejemplo, ¿cómo eliminarías la ambigüedad de lo siguiente?

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

Si paso lo siguiente, ¿cuál de los dos métodos debería ejecutarse, el que tiene el parámetro opcional o el segundo sin el segundo parámetro?

TestFunc(1)

Una mejor solución si desea incluir parámetros opcionales en su implementación de C # sería combinar los métodos primero y segundo y verificar su valor predeterminado según sea necesario:

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

Tenga en cuenta que, utilizando esta versión, VB IS puede desambiguar qué método llamar.


En la Especificación de lenguaje de Visual Basic 10 , indica eso.

Se considera que un método con parámetros opcionales tiene varias firmas, una para cada conjunto de parámetros que la persona que llama puede pasar. Por ejemplo, el siguiente método tiene tres firmas correspondientes:

Sub F(x As Short, _ Optional y As Integer = 10, _ Optional z As Long = 20)

Por lo tanto, su TestFunc(int val1, int val2 = 0) tiene dos firmas en VB, lo que TestFunc(int val1) conflicto con TestFunc(int val1) por lo que TestFunc es ambiguo.

No puedo encontrar nada en la especificación C # que dice que los parámetros opcionales se tratan como métodos con múltiples firmas. Del comportamiento que estás viendo, asumo que en C # no se considera que tengan múltiples firmas, de lo contrario obtendrías un error de compilación, lo que significa que es válido en C #. Supongo que C # elegirá el método que se llama en función de algunas reglas, ya que no puede llamar a ambos para TestFunc(0) .


Si tratas de compilar esto en VB.NET obtendrás

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

obtendrá 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.

entonces diré que VB.NET está más limitado que C # en la sobrecarga de parámetros opcional.


TestFunc es ambiguo debido a un parámetro predeterminado. Cuando se llama a TestFunc (x), no es seguro si está llamando a TestFunc con un solo parámetro o TestFunc con los 2 parámetros por defecto. El segundo parámetro es uno por defecto.