Frage

Ich habe einen Int16 Wert, aus der Datenbank, und muß dies einen Aufzählungstyp konvertieren. Dies ist leider in einer Schicht des Codes durchgeführt, die nur sehr wenig weiß über die Objekte außer dem, was sie durch die Reflexion sammeln können.

Als solches ist es endet Convert.ChangeType Aufruf, die mit einer ungültigen Guss Ausnahme fehlschlägt.

Ich fand, was ich eine stinkende Abhilfe zu prüfen, wie folgt aus:

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

Gibt es eine bessere Art und Weise, so dass ich muß nicht durch diese String Operation bewegen?

Hier ist ein kurzes, aber vollständiges, Programm, das verwendet werden kann, wenn jemand experimentieren müssen:

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);
    }
}
War es hilfreich?

Lösung

Enum.ToObject(.... ist das, was Sie suchen!

C #

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

VB.NET

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

Wenn Sie eine Menge von Enum Umwandlung Versuch mit der folgenden Klasse tun wird es Ihnen eine Menge Code speichern.

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);
    }
}

Jetzt statt zu schreiben (StringComparison)Enum.ToObject(typeof(StringComparison), 5); Sie einfach Enum<StringComparison>.ToObject(5); schreiben kann.

Andere Tipps

Auf der Grundlage des @ Peter Antwort hier ist das Verfahren zum Nullable<int> Umwandlung in 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;
        }
}

EnumUtils.TryParse<YourEnumType>(someNumber, out result) Verwendung wird nützlich für viele Szenarien. Zum Beispiel WebAPI-Controller in Asp.NET nicht standardmäßig zum Schutz vor ungültiger Enum params haben. Asp.NET wird nur default(YourEnumType) Wert verwenden, auch wenn einige Pässe null, -1000, 500000, "garbage string" oder ignoriert die Parameter. Darüber hinaus wird ModelState in allen diesen Fällen gelten, so eine der Lösung int? Typen verwenden, um mit benutzerdefinierter Prüfung ist

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
    }

Wenn Sie eine Enum in einer Datentabelle sind die Speicherung, aber nicht wissen, welche Spalte ist eine Enumeration und das ist ein String / int, können Sie den Wert auf diese Weise zugreifen:

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));
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top