29 votes

Pourquoi ce code .NET apparemment correct ne se compile-t-il pas?

Je pose la question au cas où je suis absent quelque chose d'évident, mais je pense que j'ai peut-être tombé sur un bug .NET du compilateur.

J'ai deux projets en un .NET solution, visual basic, C#.

Le code C#, composé de trois surcharge des méthodes statiques avec des valeurs par défaut:

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

Le code Visual basic, appelant l'une des méthodes surchargées:

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 compilation de ce code, sera un échec, en disant:

'TestFunc" est ambigu, car plusieurs types de membres avec ce nom existe dans la classe " ClassLibrary1.Class1'.

Pourquoi en serait-il de voir cette méthode comme ambiguë? Il y a seulement un Class1.TestFunc avec un (int, int) signature. Est-ce un bug ou ai-je raté quelque chose?

23voto

Jim Wooley Points 6323

En fin de compte, il semble venir de la façon dont C# est la mise en œuvre de l'option paramètres dans votre première méthode statique. Si vous supprimez la valeur par défaut sur que, votre solution doit compiler.

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

En fait, dans ce cas, je suis quelque peu surpris que le C# compile. Vous devez utiliser l'option paramètres en C# ou surcharges, mais pas les deux. Par exemple, comment feriez-vous pour lever l'ambiguïté sur les éléments suivants:

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

public static void TestFunc(int val1)     
{     
}  

Si je passe à la suivante, laquelle des deux méthodes doit être exécutée, l'un avec le paramètre optionnel ou le deuxième sans le deuxième paramètre?

TestFunc(1)

Une meilleure solution si vous souhaitez inclure des paramètres facultatifs dans votre C# de la mise en œuvre serait de combiner la première et la deuxième méthode et de vérifier votre valeur par défaut si nécessaire:

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

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

Noter que l'utilisation de cette version, VB, il EST possible de lever l'ambiguïté de la méthode à appeler.

15voto

xanatos Points 30513

Si vous essayez de compiler cela dans VB.NET, vous obtiendrez

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

End Sub

Sub TestFunc(Optional ByVal val1 As Integer = 0)

End Sub
 

vous obtiendrez 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.

donc je dirai que VB.NET est plus limité que C # en surcharge de paramètres optionnels.

2voto

JonH Points 20454

Éditer

Lorsque cette question a été publiée pour la première fois:

Option Strict On

et

Option Explicit On

n'ont pas été mis en question, ce qui change radicalement la réponse.

Réponse originale avant modification de la question

Car ce:

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

Est ambigu à:

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

VB.net peut convertir un entier en chaîne.

2voto

Birey Points 963

TestFunc est ambigu en raison du paramètre par défaut. Lorsque TestFunc (x) est appelé, il n'est pas sûr d'appeler TestFunc avec un seul paramètre ou TestFunc avec 2 paramètres par défaut, le 2e paramètre étant celui par défaut.

2voto

Chris Diver Points 8221

Dans le Langage Visual Basic Spécification 10 il affirme que.

Une méthode avec des paramètres optionnels est considéré comme ayant de multiples signatures, un pour chaque jeu de paramètres peuvent être passés par l'appelant. Par exemple, la méthode suivante a trois correspondants signatures:

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

Si votre TestFunc(int val1, int val2 = 0) a deux signatures en VB, ce qui contraste avec TestFunc(int val1) donc TestFunc "est ambigu.

Je ne peux pas trouver quelque chose dans la spécification C# qui dit que les paramètres facultatifs sont traités comme des méthodes avec plusieurs signatures. Par le comportement que vous voyez je suppose qu'en C# ils ne sont pas considérés comme ayant de multiples signatures, sinon vous aurez une erreur du compilateur, ce qui signifie qu'il est valide en C#. Je suppose que C# vous choisissez la méthode qui est appelée en se basant sur des règles qu'il ne peut pas appeler à la fois pour l' TestFunc(0).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X