Question

Je suis une valeur Int16, à partir de la base de données, et la nécessité de convertir en un type ENUM. Cela est malheureusement fait dans une couche du code qui sait très peu de choses sur les objets à l'exception de ce qu'il peut recueillir par la réflexion.

En tant que tel, il finit par appeler qui échoue avec Convert.ChangeType une exception coulée non valide.

J'ai trouvé ce que je considère comme une solution malodorantes, comme ceci:

String name = Enum.GetName(destinationType, value);
Object enumValue = Enum.Parse(destinationType, name, false);

Y at-il une meilleure façon, pour que je ne dois pas passer par cette opération de chaîne?

Voici un bref, mais complet, un programme qui peut être utilisé si quelqu'un a besoin d'expérimenter:

using System;

public class MyClass
{
    public enum DummyEnum
    {
        Value0,
        Value1
    }

    public static void Main()
    {
        Int16 value = 1;
        Type destinationType = typeof(DummyEnum);

        String name = Enum.GetName(destinationType, value);
        Object enumValue = Enum.Parse(destinationType, name, false);

        Console.WriteLine("" + value + " = " + enumValue);
    }
}
Était-ce utile?

La solution

Enum.ToObject(.... est ce que vous cherchez!

C #

StringComparison enumValue = (StringComparison)Enum.ToObject(typeof(StringComparison), 5);

VB.NET

Dim enumValue As StringComparison = CType([Enum].ToObject(GetType(StringComparison), 5), StringComparison)

Si vous faites beaucoup d'essayer la conversion Enum en utilisant la classe suivante, il vous permettra d'économiser beaucoup de code.

public class Enum<EnumType> where EnumType : struct, IConvertible
{

    /// <summary>
    /// Retrieves an array of the values of the constants in a specified enumeration.
    /// </summary>
    /// <returns></returns>
    /// <remarks></remarks>
    public static EnumType[] GetValues()
    {
        return (EnumType[])Enum.GetValues(typeof(EnumType));
    }

    /// <summary>
    /// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    /// <remarks></remarks>
    public static EnumType Parse(string name)
    {
        return (EnumType)Enum.Parse(typeof(EnumType), name);
    }

    /// <summary>
    /// Converts the string representation of the name or numeric value of one or more enumerated constants to an equivalent enumerated object.
    /// </summary>
    /// <param name="name"></param>
    /// <param name="ignoreCase"></param>
    /// <returns></returns>
    /// <remarks></remarks>
    public static EnumType Parse(string name, bool ignoreCase)
    {
        return (EnumType)Enum.Parse(typeof(EnumType), name, ignoreCase);
    }

    /// <summary>
    /// Converts the specified object with an integer value to an enumeration member.
    /// </summary>
    /// <param name="value"></param>
    /// <returns></returns>
    /// <remarks></remarks>
    public static EnumType ToObject(object value)
    {
        return (EnumType)Enum.ToObject(typeof(EnumType), value);
    }
}

Maintenant, au lieu d'écrire, vous pouvez simplement (StringComparison)Enum.ToObject(typeof(StringComparison), 5); écrire Enum<StringComparison>.ToObject(5);.

Autres conseils

Sur la base @ réponse de Pierre est la méthode ici pour la conversion Nullable<int> Enum:

public static class EnumUtils
{
        public static bool TryParse<TEnum>(int? value, out TEnum result)
            where TEnum: struct, IConvertible
        {
            if(!value.HasValue || !Enum.IsDefined(typeof(TEnum), value)){
                result = default(TEnum);
                return false;
            }
            result = (TEnum)Enum.ToObject(typeof(TEnum), value);
            return true;
        }
}

L'utilisation devient utile pour EnumUtils.TryParse<YourEnumType>(someNumber, out result) de nombreux scénarios. Par exemple, le contrôleur WebAPI dans Asp.NET n'a pas de protection par défaut contre params Enum invalides. Asp.NET utilisera simplement la valeur default(YourEnumType), même si certains passages null, -1000, 500000, ou ne tient absolument pas "garbage string" le paramètre. De plus, sera valable ModelState dans tous ces cas, si l'une des solutions est d'utiliser le type avec contrôle int? personnalisé

public class MyApiController: Controller
{
    [HttpGet]
    public IActionResult Get(int? myEnumParam){    
        MyEnumType myEnumParamParsed;
        if(!EnumUtils.TryParse<MyEnumType>(myEnumParam, out myEnumParamParsed)){
            return BadRequest($"Error: parameter '{nameof(myEnumParam)}' is not specified or incorrect");
        }      

        return this.Get(washingServiceTypeParsed);            
    }
    private IActionResult Get(MyEnumType myEnumParam){ 
       // here we can guarantee that myEnumParam is valid
    }

Si vous enregistrez un Enum dans un DataTable, mais ne savez pas quelle colonne est un ENUM et qui est une chaîne / int, vous pouvez accéder à la valeur de cette façon:

foreach (DataRow dataRow in myDataTable.Rows)
{
    Trace.WriteLine("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=");
    foreach (DataColumn dataCol in myDataTable.Columns)
    {
        object v = dataRow[dataCol];
        Type t = dataCol.DataType;
        bool e = false;
        if (t.IsEnum) e = true;

        Trace.WriteLine((dataCol.ColumnName + ":").PadRight(30) +
            (e ? Enum.ToObject(t, v) : v));
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top