[英]Convert.ChangeType and converting to enums?
我從數據庫中獲得了一個Int16
值,需要將其轉換為枚舉類型。 不幸的是,這是在代碼層中完成的,除了可以通過反射收集的內容外,它對對象知之甚少。
因此,它最終會調用Convert.ChangeType
,該方法因無效的強制轉換異常而失敗。
我發現了我認為很臭的解決方法,如下所示:
String name = Enum.GetName(destinationType, value);
Object enumValue = Enum.Parse(destinationType, name, false);
有沒有更好的方法,這樣我就不必通過這個 String 操作?
這是一個簡短但完整的程序,如果有人需要進行實驗,可以使用它:
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);
}
}
Enum.ToObject(....
就是你要找的!
C#
StringComparison enumValue = (StringComparison)Enum.ToObject(typeof(StringComparison), 5);
網絡
Dim enumValue As StringComparison = CType([Enum].ToObject(GetType(StringComparison), 5), StringComparison)
如果您嘗試使用以下類進行大量 Enum 轉換,它將為您節省大量代碼。
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);
}
}
現在而不是寫(StringComparison)Enum.ToObject(typeof(StringComparison), 5);
你可以簡單地寫Enum<StringComparison>.ToObject(5);
.
基於@Peter 的回答,這里是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;
}
}
使用EnumUtils.TryParse<YourEnumType>(someNumber, out result)
在許多場景中變得有用。 例如,Asp.NET 中的 WebApi 控制器沒有針對無效 Enum 參數的默認保護。 Asp.NET 將只使用default(YourEnumType)
值,即使有些傳遞null
、 -1000
、 500000
、 "garbage string"
或完全忽略參數。 此外, ModelState
在所有這些情況下都是有效的,因此解決方案之一是使用int?
輸入自定義檢查
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
}
如果您將 Enum 存儲在 DataTable 中,但不知道哪一列是枚舉,哪一列是字符串/整數,則可以通過以下方式訪問該值:
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));
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.