83 votes

Switch case en C# - une valeur constante est attendue

Mon code est le suivant :

public static void Output<T>(IEnumerable<T> dataSource) where T : class
{   
    dataSourceName = (typeof(T).Name);
    switch (dataSourceName)
    {
        case (string)typeof(CustomerDetails).Name.ToString(); :
            var t = 123;
            break;
        default:
            Console.WriteLine("Test");
    }
}

Mais cela ne fonctionne pas. L'instruction case me donne un message d'erreur disant qu'une variable constante est attendue. Aidez-moi, s'il vous plaît, merci !

0 votes

48voto

deepee1 Points 4449

Voir Limitations de l'instruction switch en C# - pourquoi ?

Fondamentalement, les commutateurs ne peuvent pas avoir d'instructions évaluées dans l'instruction case. Ils doivent être évalués de manière statique.

7 votes

Ce n'est pas vrai en VB.net... J'essaie de convertir un code qui a déjà ce type de valeurs de cas (essentiellement des appels de méthodes).

6 votes

@Moslem Ben Dhaou oui C# Switch n'est définitivement pas équivalent à l'instruction Case de VB. Pour les instructions Case, vous pouvez utiliser des expressions (appels de fonctions, variables, etc.) alors que le C# a besoin de valeurs constantes (pas d'appels de fonctions, de variables, etc.). L'instruction switch est assez limitée en comparaison.

39voto

Maximilian Mayerl Points 6335

Vous pouvez uniquement faire correspondre des constantes dans les instructions de commutation.


Ejemplo:

switch (variable1)
{
    case 1: // A hard-coded value
        // Code
        break;
    default:
        // Code
        break;
}

Succès !


switch (variable1)
{
    case variable2:
        // Code
        break;
    default:
        // Code
        break;
}

CS0150 Une valeur constante est attendue.

30 votes

Remarque supplémentaire : "const int myConstant = 3" compte comme une constante, mais "readonly static int myReadonlyStatic = 3" ne compte pas.

20voto

0xF Points 149

Vous pouvez maintenant utiliser nameof :

public static void Output<T>(IEnumerable<T> dataSource) where T : class
{
    string dataSourceName = typeof(T).Name;
    switch (dataSourceName)
    {
        case nameof(CustomerDetails):
            var t = 123;
            break;
        default:
            Console.WriteLine("Test");
    }
}

nameof(CustomerDetails) est fondamentalement identique à la chaîne littérale "CustomerDetails" mais avec une vérification au moment de la compilation qu'il se réfère à un symbole (pour éviter une erreur de frappe).

nameof est apparu dans C# 6.0, donc après que cette question ait été posée.

14voto

iDevForFun Points 583

Vous ne pouvez pas utiliser une instruction switch pour cela, car les valeurs des cas ne peuvent pas être des expressions évaluées. Pour cela, vous devez utiliser une instruction if/else ...

public static void Output<T>(IEnumerable<T> dataSource) where T : class
{   
    dataSourceName = (typeof(T).Name);
    if(string.Compare(dataSourceName, typeof(CustomerDetails).Name.ToString(), true)==0)
    {
        var t = 123;
    }
    else if (/*case 2 conditional*/)
    {
        //blah
    }
    else
    {
        //default case
        Console.WriteLine("Test");
    }
}

J'ai également pris la liberté de mettre de l'ordre dans votre déclaration conditionnelle. Il n'est pas nécessaire de convertir en chaîne de caractères après avoir appelé ToString() . De toute façon, cela renvoie toujours une chaîne de caractères. Lorsque vous comparez des chaînes de caractères pour vérifier leur égalité, n'oubliez pas que l'utilisation de l'opérateur == entraînera une comparaison sensible à la casse. Il est préférable d'utiliser string compare = 0 avec le dernier argument pour activer ou désactiver la sensibilité à la casse.

11voto

MjH Points 389

Il y a cette astuce dont on m'a fait part (ne demandez pas de détails - je ne pourrai pas les fournir, mais ça marche pour moi) :

switch (variable_1)
{
    case var value when value == variable_2: // that's the trick
        DoSomething();
        break;
    default:
        DoSomethingElse();
        break;
}

0 votes

Aïe, merci ! !! Pourquoi diable cela fonctionne-t-il ? !?! Il fonctionne avec le C# 8.0 commutateur de variable lambda aussi : variable_1 switch var value when value == variable_2:

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