Tous les énumérations doivent utiliser l'un des types suivants dans leur déclaration: byte
, sbyte
, short
, ushort
, int
, uint
, long
ou ulong
. Voici comment vous spécifiez un type:
enum MyEnum3 : long {
Value1 = 5L,
Value2 = 9L,
Value3 = long.MaxValue
}
Si vous ne spécifiez pas de type, la valeur par défaut est int
.
Malheureusement, vous ne pouvez pas spécifier char
comme type sous-jacent. Vous pouvez créer cette « extension » comme un attribut personnalisé:
[AttributeUsage(AttributeTargets.Enum)]
public class CharAttribute : Attribute { }
[Char] enum MyEnum2 {
Value1 = 'a',
Value2 = 'b',
Value3 = 'c'
}
Et puis une classe comme ceci:
public static class EnumEx {
public static Type GetUnderlyingType(Type enumType) {
if (!enumType.IsEnum) throw new ArgumentException();
if (enumType.GetCustomAttributes(typeof(CharAttribute), false).Length > 0) {
return typeof(char);
}
return Enum.GetUnderlyingType(enumType);
}
public static object ConvertToUnderlyingType(object enumValue) {
return Convert.ChangeType(enumValue,
GetUnderlyingType(enumValue.GetType()));
}
}
(Soit dit en passant, la méthode Enum.GetUnderlyingType
semble être celui que vous recherchez, mais il ne retourne jamais char
parce que vous ne pouvez pas avoir ombles énumérations dans la langue)
Cela vous permettra d'accéder à votre extension de la notion de type char énumérations:.
var value3 = EnumEx.ConvertToUnderlyingType(MyEnum2.Value3);
Console.WriteLine(value3);
Ceci affichera c
sur la console.
Faites attention au type sous-jacent et aux valeurs de vos énumérations char, ils devraient idéalement entrer dans un char
pour éviter les échecs de conversion (débordements). Les types de sécurité ont une largeur de 16 bits (exactement comme char
) ou moins: byte
, sbyte
, short
ou ushort
. D'autres types sont OK si les valeurs de l'énumération peuvent être converties en caractères de 16 bits sans perte de précision (comme dans l'exemple ci-dessus). L'utilisation des littéraux sous-jacents de type et de char sous-jacents (int
) en tant que valeurs enum (qui sont implicitement convertibles en int
) est suffisant.
MISE À JOUR:
Vous pouvez déclarer char ENUM en F #:
namespace Drawing
type Color =
| Red = 'r'
| Green = 'g'
| Blue = 'b'
En C#, vous pouvez l'utiliser comme ceci:
Console.WriteLine(Enum.GetUnderlyingType(typeof(Color)));
Et il imprimera System.Char
.
Mais ... C# se plaindra si vous essayez d'utiliser ses valeurs. Ce:
Console.WriteLine(Color.Red.ToString());
donne une erreur du compilateur:
error CS0570: 'Drawing.Color.Red' is not supported by the language
En VB.NET il n'y a pas d'erreur de compilation, mais il y a une erreur d'exécution de Enum.GetName
. Il semble que le temps d'exécution n'est pas prêt à traiter avec des enums de char. Voici un extrait de cette méthode (du réflecteur):
if (((!type.IsEnum && (type != intType)) && ((type != typeof(short)) && (type != typeof(ushort)))) && (((type != typeof(byte)) && (type != typeof(sbyte))) && (((type != typeof(uint)) && (type != typeof(long))) && (type != typeof(ulong)))))
{
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");
}
Il vérifie non seulement que le type est un ENUM, mais il est aussi l'un des types susmentionnés sous-jacents (pour lesquels l'omble est pas une option) . Vous ne devriez donc pas créer de char enums en F #. Vous pouvez utiliser l'approche "extension" que j'ai décrite.
C'est la conclusion à laquelle je suis parvenu. Je me suis dit que C# le traitait comme un entier, mais j'avais besoin de quelqu'un pour le confirmer. Merci :) –
@Nathan: J'ai modifié la réponse pour en inclure un peu plus. Fondamentalement, vous ne pouvez pas avoir un type de char sous-jacent. –