J'ai défini un enum C # comme
public enum ORDER
{
...
unknown,
partial01,
partial12,
partial23,
}
et peut utiliser sa valeur sous forme de chaîne comme dans:
string ss = ORDER.partial01.ToString();
Cependant, lorsque j'essaie de l'utiliser dans une instruction case, la compilation échoue:
string value = ...
switch (value)
{
case null:
break;
case "s":
// OK
break;
case ORDER.partial01.ToString():
// compiler throws "a constant value is expected"
break;
...
Je pensais que les enums étaient des constantes. Comment puis-je contourner cela?
(Je ne peux pas analyser la valeur dans un enum car certaines valeurs sont en dehors de la plage)
L'énumération est une constante, mais le résultat de .ToString () ne l'est pas. En ce qui concerne le compilateur, il s'agit d'une valeur dynamique. Vous aurez probablement besoin de convertir votre cas de commutateur en une série d'instructions if/else
Depuis le n ° 6, vous pouvez utiliser: case nameof(SomeEnum.SomeValue):
Nameof est évalué au moment de la compilation, simplement en une chaîne qui correspond au nom (non qualifié) de la variable, du type ou du membre donné. Naturellement, cela change si vous renommez le nom de l'option enum.
Convertissez la chaîne de votre commutateur en valeur enum.
(ORDER)Enum.Parse(typeof(ORDER), value, true);
Au lieu d'utiliser if .. else
, vous pouvez d'abord convertir votre chaîne en enum
. Cela n’aurait probablement aucun sens si le nombre d’options est limité:
if (Enum.IsDefined(typeof(ORDER), value))
{
switch ((ORDER)Enum.Parse(typeof(ORDER), value)
{
case ORDER.partial01:
// ...
break;
case ORDER.partial12:
// etc
}
}
else
{
// Handle values not in enum here if needed
}
* soupir * si seulement il y avait un T Enum.Parse<T>(string value)
intégré et une version de TryParse :)
Vous avez conçu cela comme une énumération pour une raison, mais vous ne l'utilisez pas vraiment comme une énumération. Pourquoi prenez-vous la valeur enum et la convertissez-vous en chaîne à utiliser ensuite dans le commutateur au lieu de simplement utiliser l'énum?
Vous avez dit que vous ne pouvez pas analyser cela en une énumération, car certaines valeurs sont en dehors de la plage enum. La question à poser est alors: "Pourquoi?" Quel est l'intérêt d'avoir l'énumération si vous autorisez des valeurs qui ne sont pas définies? Que voulez-vous que se produise lorsque vous obtenez une valeur qui n'est pas définie? Si c'est la même chose pour toute valeur indéfinie, vous pouvez utiliser le cas par défaut. Si ce n'est pas le cas, vous pouvez inclure d'autres cas qui correspondent à la représentation numérique.
Si vous récupérez réellement des chaînes, vous ne voudrez probablement pas utiliser d'énum. Au lieu de cela, vous souhaitez créer une classe statique publique contenant des constantes de chaîne publiques, que vous pouvez ensuite utiliser dans votre commutateur. L'astuce ici est que l'évaluation se fera de manière sensible à la casse.
public static class Order
{
public const string Unknown = "Unknown";
public const string Partial01 = "Partial01";
public const string Partial12 = "Partial12";
public const string Partial23 = "Partial23";
}
string value = Order.Partial01
switch (value)
{
case Order.Partial01:
break;
default:
// Code you might want to run in case you are
// given a value that doesn't match.
break;
}
(Vous pouvez aussi vouloir nettoyer votre boîtier.)
Comme Thorarin l'a indiqué, si votre instruction switch
ne peut contenir que des cas enum
, convertissez d'abord votre string
en enum
. Au moins à partir de .NET Framework 4, vous pouvez utiliser la méthode Enum.TryParse()<TEnum>
telle que définie ici et faire quelque chose comme:
ORDER orderEnum = ORDER.unknown;
Enum.TryParse<ORDER>(value, out orderEnum);
switch (orderEnum)
{
case ORDER.unknown:
// perhaps do something to deal with cases not matching
// to known enum values, based on the string value
break;
case ORDER.partial01:
case ORDER.partial12:
case ORDER.partial23:
// map value to known cases, etc.
break;
}
Les valeurs Enum sont des constantes, mais vous essayez d'utiliser les résultats d'une méthode (ORDER.partial01.ToString ()) et non d'une constante.
La meilleure option, à mon avis, consisterait simplement à changer cela en utilisant des instructions if/else if/else, au lieu d'un commutateur. Cela vous permettrait d'utiliser la logique que vous désirez.
Si vous passez votre chaîne dans la valeur enum, vous pouvez également activer directement les valeurs enum. Vous ne pouvez cependant pas activer l'enum + null + d'autres chaînes dans un seul commutateur.
Ne pourriez-vous pas simplement dire
case "partial01":
?
les énumérations sont constantes mais ToString () est une fonction renvoyant une valeur. sur la base de l'instance de l'objet enum, il est appelé.
Ce sont les deux déclarations:
ORDER.partial01.ToString()
ORDER.partial02.ToString()
appelle la même fonction mais renvoie deux valeurs différentes, l'appel à la fonction .ToString () est donc une valeur constante.
Ce n'est pas une valeur statique pour le compilateur puisqu'il s'agit d'un appel de fonction:
ORDER.partial01.ToString()
Par conséquent, vous ne pouvez pas l'utiliser comme comparaison dans une instruction case. Cependant, vous pouvez simplement faire ceci:
case "partial01"
Cela fonctionnerait, puisque la valeur enum et la chaîne sont identiques.
Utiliser l'extension
public static string ToGender(this Gender enumValue)
{
switch (enumValue)
{
case Gender.Female:
return "Female";
case Gender.Male:
return "Male";
default:
return null;
}
}
Exemple
Gender.Male.ToGender();
vous pouvez simplement définir une variable globale
static ORDER orderstr;
maintenant vous pouvez définir la valeur de orderstr
n'importe où dans la page
public enum ORDER
{
unknown,
partial01,
partial12,
partial23,
}
switch (orderstr)
{
case Order.Partial01:
break;
default:
break;
}