2009-09-15 10 views
5

Je me demande est-il un moyen d'empêcher un enum avec des clés en double à compiler?Comment éviter les doublons dans une énumération?

Par exemple ce enum ci-dessous compilera

public enum EDuplicates 
{ 
    Unique, 
    Duplicate = 0, 
    Keys = 1, 
    Compilation = 1 
} 

Bien que ce code

Console.WriteLine(EDuplicates.Unique); 
Console.WriteLine(EDuplicates.Duplicate); 
Console.WriteLine(EDuplicates.Keys); 
Console.WriteLine(EDuplicates.Compilation); 

va imprimer

Duplicate 
Duplicate 
Keys 
Keys 
+1

Ah les joies de Java énumérations. :) – cletus

+1

Ceci est C#. :-) –

+0

Voir le lien suivant pour savoir pourquoi 'Console.WriteLine (EDelectes.Unique);' prints 'Duplicate' http://stackoverflow.com/questions/530281/unexpected-result-when-using-enum-parse –

Répondre

14

Ce n'est pas interdit par la spécification du langage, de sorte que tout conforme Compilateur C# devrait le permet. Vous pouvez toujours adapter le compilateur Mono pour l'interdire - mais franchement, il serait plus simple d'écrire un test unitaire pour analyser vos assemblys et les appliquer de cette façon.

+2

Je manque probablement le point ici: Quel est le scénario utile pour soutenir cela? S'il n'y a pas de scénarios utiles, pourquoi préféreriez-vous écrire des tests unitaires pour cela, laissant le compilateur gérer la situation? –

+0

@Brian: Pour éviter de casser le code existant. La rétrocompatibilité est importante, tout comme la conformité à la spécification. Je ne peux pas immédiatement penser à des scénarios utiles, mais cela ne signifie pas que je voudrais casser quelqu'un qui l'utilise déjà. –

+6

@Brian: Cela peut être utile si, pour une raison quelconque, vous souhaitez changer le nom d'une valeur enum sans casser l'ancien code: ajoutez une nouvelle valeur avec le nouveau nom et la même valeur numérique que l'ancienne et décorez l'ancienne valeur avec l'attribut 'Obsolete'. –

0
public bool ValidateAllDistinct(Type enumType) 
{ 
    return !Enum.GetNames(enumType).All(outerName 
     => Enum.GetNames(enumType).Any(innerName 
      => innerName == outerName 
       ? true 
       : Enum.Parse(enumType, innerName) != Enum.Parse(enumType, outerName))); 
} 

I méthode de test simple pour votre unittest.

+0

C'est quelque chose comme le test d'unité que j'avais dû écrire avec seulement une différence que j'imprime des clés en double. – zzandy

+0

Accorder à [ce] (https://dotnetfiddle.net/0KoChn) violon ne fonctionne pas. Corrigez-moi si j'ai raté quelque chose. – LosManos

9

est ici un simple test de l'unité qu'il contrôle, devrait être un peu plus rapide:

[TestMethod] 
public void Test() 
{ 
    var enums = (myEnum[])Enum.GetValues(typeof(myEnum)); 
    Assert.IsTrue(enums.Count() == enums.Distinct().Count()); 
} 
Questions connexes