parse Cast int à enum en C#




int to enum java (14)

Comment un int peut-il être converti en une enum en C #?

https://code.i-harness.com


À partir d'une chaîne: (Enum.Parse est obsolète, utilisez Enum.TryParse)

enum Importance
{}

Importance importance;

if (Enum.TryParse(value, out importance))
{
}

À partir d'une chaîne:

YourEnum foo = (YourEnum) Enum.Parse(typeof(YourEnum), yourString);
// the foo.ToString().Contains(",") check is necessary for enumerations marked with an [Flags] attribute
if (!Enum.IsDefined(typeof(YourEnum), foo) && !foo.ToString().Contains(","))
  throw new InvalidOperationException($"{yourString} is not an underlying value of the YourEnum enumeration.")

D'un int:

YourEnum foo = (YourEnum)yourInt;

Mettre à jour:

De nombre vous pouvez aussi

YourEnum foo = (YourEnum)Enum.ToObject(typeof(YourEnum) , yourInt);

Ceci analyse des entiers ou des chaînes en une énumération cible avec une correspondance partielle dans dot.NET 4.0 à l'aide de génériques comme dans la classe d'utilitaires de Tawani ci-dessus. Je l'utilise pour convertir des variables de commutateur de ligne de commande qui peuvent être incomplètes. Comme une énumération ne peut pas être nulle, vous devez logiquement fournir une valeur par défaut. On peut appeler ça comme ça:

var result = EnumParser<MyEnum>.Parse(valueToParse, MyEnum.FirstValue);

Voici le code:

using System;

public class EnumParser<T> where T : struct
{
    public static T Parse(int toParse, T defaultVal)
    {
        return Parse(toParse + "", defaultVal);
    }
    public static T Parse(string toParse, T defaultVal) 
    {
        T enumVal = defaultVal;
        if (defaultVal is Enum && !String.IsNullOrEmpty(toParse))
        {
            int index;
            if (int.TryParse(toParse, out index))
            {
                Enum.TryParse(index + "", out enumVal);
            }
            else
            {
                if (!Enum.TryParse<T>(toParse + "", true, out enumVal))
                {
                    MatchPartialName(toParse, ref enumVal);
                }
            }
        }
        return enumVal;
    }

    public static void MatchPartialName(string toParse, ref T enumVal)
    {
        foreach (string member in enumVal.GetType().GetEnumNames())
        {
            if (member.ToLower().Contains(toParse.ToLower()))
            {
                if (Enum.TryParse<T>(member + "", out enumVal))
                {
                    break;
                }
            }
        }
    }
}

FYI: La question portait sur les entiers, que personne n'a mentionné ne sera également explicitement converti en Enum.TryParse ()


Ci-dessous, une belle classe utilitaire pour Enums

public static class EnumHelper
{
    public static int[] ToIntArray<T>(T[] value)
    {
        int[] result = new int[value.Length];
        for (int i = 0; i < value.Length; i++)
            result[i] = Convert.ToInt32(value[i]);
        return result;
    }

    public static T[] FromIntArray<T>(int[] value) 
    {
        T[] result = new T[value.Length];
        for (int i = 0; i < value.Length; i++)
            result[i] = (T)Enum.ToObject(typeof(T),value[i]);
        return result;
    }


    internal static T Parse<T>(string value, T defaultValue)
    {
        if (Enum.IsDefined(typeof(T), value))
            return (T) Enum.Parse(typeof (T), value);

        int num;
        if(int.TryParse(value,out num))
        {
            if (Enum.IsDefined(typeof(T), num))
                return (T)Enum.ToObject(typeof(T), num);
        }

        return defaultValue;
    }
}

Différentes façons de lancer à et de Enum

enum orientation : byte
{
 north = 1,
 south = 2,
 east = 3,
 west = 4
}

class Program
{
  static void Main(string[] args)
  {
    orientation myDirection = orientation.north;
    Console.WriteLine(“myDirection = {0}”, myDirection); //output myDirection =north
    Console.WriteLine((byte)myDirection); //output 1

    string strDir = Convert.ToString(myDirection);
        Console.WriteLine(strDir); //output north

    string myString = “north”; //to convert string to Enum
    myDirection = (orientation)Enum.Parse(typeof(orientation),myString);


 }
}

Il peut vous aider à convertir les données d’entrée en un enum souhaité par l’utilisateur. Supposons que vous ayez une énumération comme ci-dessous qui, par défaut, int . Veuillez ajouter une valeur par défaut au début de votre énumération. Qui est utilisé par medersh quand il n’ya pas de correspondance avec la valeur en entrée.

public enum FriendType  
{
    Default,
    Audio,
    Video,
    Image
}

public static class EnumHelper<T>
{
    public static T ConvertToEnum(dynamic value)
    {
        var result = default(T);
        var tempType = 0;

        //see Note below
        if (value != null &&
            int.TryParse(value.ToString(), out  tempType) && 
            Enum.IsDefined(typeof(T), tempType))
        {
            result = (T)Enum.ToObject(typeof(T), tempType); 
        }
        return result;
    }
}

NB: J'essaye ici d'analyser la valeur dans int, car enum est par défaut int Si vous définissez enum comme ceci, il s'agit d' un type d' octet .

public enum MediaType : byte
{
    Default,
    Audio,
    Video,
    Image
} 

Vous devez changer la méthode d'analyse syntaxique à partir de

int.TryParse(value.ToString(), out  tempType)

à

byte.TryParse(value.ToString(), out tempType)

Je vérifie ma méthode pour les entrées suivantes

EnumHelper<FriendType>.ConvertToEnum(null);
EnumHelper<FriendType>.ConvertToEnum("");
EnumHelper<FriendType>.ConvertToEnum("-1");
EnumHelper<FriendType>.ConvertToEnum("6");
EnumHelper<FriendType>.ConvertToEnum("");
EnumHelper<FriendType>.ConvertToEnum("2");
EnumHelper<FriendType>.ConvertToEnum(-1);
EnumHelper<FriendType>.ConvertToEnum(0);
EnumHelper<FriendType>.ConvertToEnum(1);
EnumHelper<FriendType>.ConvertToEnum(9);

Désolé pour mon anglais


Il suffit de le lancer:

MyEnum e = (MyEnum)3;

Vous pouvez vérifier si c'est dans la plage en utilisant Enum.IsDefined :

if (Enum.IsDefined(typeof(MyEnum), 3)) { ... }

J'utilise ce morceau de code pour lancer int à mon enum:

if (typeof(YourEnum).IsEnumDefined(valueToCast)) return (YourEnum)valueToCast;
else { //handle it here, if its not defined }

Je trouve la meilleure solution.


Je pense que pour obtenir une réponse complète, il faut que les gens sachent comment fonctionnent les enums en interne dans .NET.

Comment ça marche

Une énumération dans .NET est une structure qui mappe un ensemble de valeurs (champs) à un type de base (la valeur par défaut est int ). Cependant, vous pouvez réellement choisir le type d'intégrale auquel votre énumération correspond:

public enum Foo : short

Dans ce cas, l'énumération est mappée sur le type de données short , ce qui signifie qu'elle sera stockée en mémoire sous forme de mémoire et se comportera comme telle lors de son utilisation.

Si vous le regardez d'un point de vue IL, un enum (normal, int) ressemble à ceci:

.class public auto ansi serializable sealed BarFlag extends System.Enum
{
    .custom instance void System.FlagsAttribute::.ctor()
    .custom instance void ComVisibleAttribute::.ctor(bool) = { bool(true) }

    .field public static literal valuetype BarFlag AllFlags = int32(0x3fff)
    .field public static literal valuetype BarFlag Foo1 = int32(1)
    .field public static literal valuetype BarFlag Foo2 = int32(0x2000)

    // and so on for all flags or enum values

    .field public specialname rtspecialname int32 value__
}

Ce qui devrait attirer votre attention ici est que la value__ est stockée séparément des valeurs enum. Dans le cas de l'énumération Foo ci-dessus, le type de value__ est int16. Cela signifie essentiellement que vous pouvez stocker ce que vous voulez dans une énumération, à condition que les types correspondent .

À ce stade, je voudrais souligner que System.Enum est un type de valeur, ce qui signifie que BarFlag utilisera 4 octets en mémoire et Foo , 2 - par exemple, la taille du type sous-jacent (en réalité plus compliqué que ça, mais bon ...).

La réponse

Ainsi, si vous souhaitez mapper un entier sur une énumération, le moteur d'exécution ne doit effectuer que 2 choses: copier les 4 octets et lui attribuer un autre nom (le nom de l'énumération). La copie est implicite car les données sont stockées en tant que type de valeur. En d'autres termes, si vous utilisez du code non managé, vous pouvez simplement échanger des enum et des entiers sans copier les données.

Pour plus de sécurité, je pense qu'il est préférable de savoir que les types sous-jacents sont identiques ou implicitement convertibles et de s'assurer que les valeurs enum existent (elles ne sont pas cochées par défaut!).

Pour voir comment cela fonctionne, essayez le code suivant:

public enum MyEnum : int
{
    Foo = 1,
    Bar = 2,
    Mek = 5
}

static void Main(string[] args)
{
    var e1 = (MyEnum)5;
    var e2 = (MyEnum)6;

    Console.WriteLine("{0} {1}", e1, e2);
    Console.ReadLine();
}

Notez que la conversion en e2 fonctionne également! Du point de vue du compilateur ci-dessus, cela a du sens: le champ value__ est simplement rempli avec 5 ou 6 et lorsque Console.WriteLine appelle ToString() , le nom de e1 est résolu alors que le nom de e2 ne l’est pas.

Si ce n'est pas ce que vous vouliez, utilisez Enum.IsDefined(typeof(MyEnum), 6) pour vérifier si la valeur que vous Enum.IsDefined(typeof(MyEnum), 6) correspondance avec une énumération définie.

Notez également que je suis explicite sur le type sous-jacent de l'énum, ​​même si le compilateur vérifie réellement cela. Je fais cela pour m'assurer de ne pas avoir de surprises par la suite. Pour voir ces surprises en action, vous pouvez utiliser le code suivant (en fait, j'ai souvent vu cela se produire dans le code de la base de données):

public enum MyEnum : short
{
    Mek = 5
}

static void Main(string[] args)
{
    var e1 = (MyEnum)32769; // will not compile, out of bounds for a short

    object o = 5;
    var e2 = (MyEnum)o;     // will throw at runtime, because o is of type int

    Console.WriteLine("{0} {1}", e1, e2);
    Console.ReadLine();
}

Légèrement en m'éloignant de la question initiale, mais j'ai trouvé une réponse à la question Get int value of enum utile. Créez une classe statique avec public const int propriétés public const int , ce qui vous permet de facilement rassembler un ensemble de constantes int associées, sans avoir à les int en int lors de leur utilisation.

public static class Question
{
    public static readonly int Role = 2;
    public static readonly int ProjectFunding = 3;
    public static readonly int TotalEmployee = 4;
    public static readonly int NumberOfServers = 5;
    public static readonly int TopBusinessConcern = 6;
}

De toute évidence, certaines fonctionnalités de type énumération seront perdues, mais pour stocker un grand nombre de constantes id de base de données, cela semble être une solution plutôt ordonnée.


Pour les valeurs numériques, cela est plus sûr car cela retournera un objet, peu importe quoi:

public static class EnumEx
{
    static public bool TryConvert<T>(int value, out T result)
    {
        result = default(T);
        bool success = Enum.IsDefined(typeof(T), value);
        if (success)
        {
            result = (T)Enum.ToObject(typeof(T), value);
        }
        return success;
    }
}

Prenons l'exemple suivant:

int one = 1;
MyEnum e = (MyEnum)one;

Si vous avez un entier faisant office de masque binaire et pouvant représenter une ou plusieurs valeurs dans une énumération [Flags], vous pouvez utiliser ce code pour analyser les valeurs d'indicateur individuelles dans une liste:

for (var flagIterator = 0x1; flagIterator <= 0x80000000; flagIterator <<= 1)
{
    // Check to see if the current flag exists in the bit mask
    if ((intValue & flagIterator) != 0)
    {
        // If the current flag exists in the enumeration, then we can add that value to the list
        // if the enumeration has that flag defined
        if (Enum.IsDefined(typeof(MyEnum), flagIterator))
            ListOfEnumValues.Add((MyEnum)flagIterator);
    }
}

Sinon, utilisez une méthode d'extension à la place d'une ligne:

public static T ToEnum<T>(this string enumString)
{
    return (T) Enum.Parse(typeof (T), enumString);
}

Usage:

Color colorEnum = "Red".ToEnum<Color>();

OU

string color = "Red";
var colorEnum = color.ToEnum<Color>();




casting