Ich habe einen Int16
Wert aus der Datenbank erhalten und muss diesen in einen Aufzählungstyp konvertieren. Dies geschieht leider in einer Ebene des Codes, die nur sehr wenig über die Objekte weiß, außer was sie durch Reflexion sammeln können.
Als solches wird ein Aufruf ausgeführt, Convert.ChangeType
der mit einer ungültigen Besetzungsausnahme fehlschlägt.
Ich fand eine meiner Meinung nach stinkende Problemumgehung wie folgt:
String name = Enum.GetName(destinationType, value);
Object enumValue = Enum.Parse(destinationType, name, false);
Gibt es einen besseren Weg, damit ich mich nicht durch diese String-Operation bewegen muss?
Hier ist ein kurzes, aber vollständiges Programm, das verwendet werden kann, wenn jemand experimentieren muss:
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);
}
}
c#
enums
changetype
Lasse V. Karlsen
quelle
quelle
Antworten:
Enum.ToObject(....
ist was du suchst!C #
StringComparison enumValue = (StringComparison)Enum.ToObject(typeof(StringComparison), 5);
VB.NET
Dim enumValue As StringComparison = CType([Enum].ToObject(GetType(StringComparison), 5), StringComparison)
Wenn Sie viel Enum-Konvertierung durchführen und versuchen, die folgende Klasse zu verwenden, sparen Sie viel 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); } }
Anstatt zu schreiben
(StringComparison)Enum.ToObject(typeof(StringComparison), 5);
, können Sie jetzt einfach schreibenEnum<StringComparison>.ToObject(5);
.quelle
ToObject()
scheint Werte zuzulassen, die in der Aufzählung nicht vorhanden sind, und auch Werte außerhalb des Bereichs des zugrunde liegenden Typs:Enum.ToObject(typeof(IntEnumType), (long)Int32.MaxValue + 1)
Basierend auf der Antwort von @ Peter ist hier die Methode
Nullable<int>
zurEnum
Konvertierung: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; } }
Die Verwendung
EnumUtils.TryParse<YourEnumType>(someNumber, out result)
wird für viele Szenarien nützlich. Beispielsweise verfügt WebApi Controller in Asp.NET nicht über einen Standardschutz gegen ungültige Enum-Parameter. Asp.NET wird nur verwendendefault(YourEnumType)
Wert, auch wenn einige Pässenull
,-1000
,500000
,"garbage string"
oder vollständig die Parameter ignoriert. Darüber hinaus istModelState
in all diesen Fällen gültig, sodass eine der Lösungen darin besteht, denint?
Typ mit benutzerdefinierter Prüfung zu verwendenpublic 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 }
quelle
Wenn Sie eine Aufzählung in einer Datentabelle speichern, aber nicht wissen, welche Spalte eine Aufzählung und welche eine Zeichenfolge / int ist, können Sie auf folgende Weise auf den Wert 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)); } }
quelle