2010-08-25 140 views
34

枚舉值我有一個簡單枚舉獲得通過反射

public enum TestEnum 
{ 
    TestOne = 3, 
    TestTwo = 4 
} 

var testing = TestEnum.TestOne; 

我想要檢索通過反射它的值(3)。任何想法如何做到這一點?

+0

要發表評論:在任何意義上'有'TestEnum.TestOne值的環境中,*已經*值爲'3'。你實際上有什麼? – AakashM 2010-08-25 12:01:27

回答

38

偉大的問題墊。

問題的情形是這樣的:

你有一些未知的枚舉類型和一些未知值類型的,你想獲取未知值的基礎數值

這是這樣使用反射的一個聯機方式:

object underlyingValue = Convert.ChangeType(value, Enum.GetUnderlyingType(value.GetType())); 

如果值碰巧是TestEnum.TestTwo,然後value.GetType()將等於typeof(TestEnum)Enum.GetUnderlyingType(value.GetType())將等於typeof(int)和值將是3(裝箱;有關裝箱和拆箱值的更多詳細信息,請參閱http://msdn.microsoft.com/en-us/library/yz2be5wk.aspx)。

爲什麼有人需要編寫這樣的代碼?就我而言,我有一個將視圖模型中的值複製到模型的例程。我在ASP.NET MVC項目的所有處理程序中都使用它作爲非常乾淨優雅的編寫處理程序的一部分,該處理程序沒有Microsoft模板生成的處理程序所產生的安全問題。

該模型由Entity Framework從數據庫生成,它包含一個int類型的字段。 viewmodel有一些枚舉類型的字段,我們稱之爲RecordStatus,這是我在項目中其他地方定義的。我決定在我的框架中完全支持枚舉。但現在模型中的字段類型與視圖模型中相應字段的類型之間存在不匹配。我的代碼檢測到這一點,並使用類似於上面給出的單行代碼將枚舉轉換爲int。

+3

你的回答對你自問的問題是一個很好的答案,但我不認爲這是對這裏提出的問題的回答。 – hvd 2012-11-14 11:48:56

+6

感謝您的評論,但實際上這*是* Mat問的答案。 – 2012-11-16 08:40:19

+3

更具體地說,Mat問他如何使用反射*獲取某個簡單枚舉類型(TestEnum)*的枚舉值(測試)的(基礎)值(3)。丹尼爾和弗雷德裏克假定他問的是錯誤的東西,並回答說反射是不必要的,普蘭奈完全回答了一個不同的問題(如何使用反射列出枚舉類型的值)。這正是因爲目前有迴應的答案沒有解決我提出的問題,並且回答了這個問題,並舉了一個例子,說明一個人可能想要完全按照Mat的要求去做的事情! :-) – 2012-11-16 09:03:08

1

無需反思:

int value = (int)TestEnum.TestOne; 
+0

又一次我知道如何做到這一點。但我需要使用反射 – 2010-08-25 11:41:42

+6

@mjmcloug:如果你擴展你的問題的簡要信息*爲什麼*你需要使用反射和你的用例,你會得到更好的答案:) – 2010-08-25 11:48:20

5

爲什麼你需要反思?

int value = (int)TestEnum.TestOne; 
+1

偉大的思想認爲一樣。並在同一秒,似乎:) – 2010-08-25 11:28:05

+6

;)是的,我知道如何做到這一點。但我需要使用反射 – 2010-08-25 11:41:15

+2

這是因爲我們不知道TestEnum類型,我們只知道我們有一個枚舉。 – 2014-02-27 16:17:22

16

全碼:How to Get Enum Values with Reflection in C#

MemberInfo[] memberInfos = typeof(MyEnum).GetMembers(BindingFlags.Public | BindingFlags.Static); 
string alerta = ""; 
for (int i = 0; i < memberInfos.Length; i++) { 
alerta += memberInfos[i].Name + " - "; 
alerta += memberInfos[i].GetType().Name + "\n"; 
} 
+10

我沒有-1,但我猜測即使答案是正確的,但它不是很具描述性。這裏有一個鏈接和一些代碼,弄清楚。它可以通過幾種方式變得更好,其中之一是提供樣本輸出。 – 2013-09-22 20:27:02

-1

或者,如果你需要的(類型TestEnum)實際枚舉對象:

MemberInfo[] memberInfos = typeof(MyEnum).GetMembers(BindingFlags.Public | BindingFlags.Static); 
string alerta = ""; 
for (int i = 0; i < memberInfos.Length; i++) { 

alerta += memberInfos[i].Name + " - "; 


/* alerta += memberInfos[i].GetType().Name + "\n"; */ 

// the actual enum object (of type MyEnum, above code is of type System.Reflection.RuntimeFieldInfo) 
object enumValue = memberInfos[i].GetValue(0); 
alerta += enumValue.ToString() + "\n"; 
} 
19

您可以使用系統。枚舉助手:

System.Type enumType = typeof(TestEnum); 
System.Type enumUnderlyingType = System.Enum.GetUnderlyingType(enumType); 
System.Array enumValues = System.Enum.GetValues(enumType); 

for (int i=0; i < enumValues.Length; i++) 
{ 
    // Retrieve the value of the ith enum item. 
    object value = enumValues.GetValue(i); 

    // Convert the value to its underlying type (int, byte, long, ...) 
    object underlyingValue = System.Convert.ChangeType(value, enumUnderlyingType); 

    System.Console.WriteLine(underlyingValue); 
} 

輸出

+4

這是更好的答案。因爲我在這裏遇到同樣的問題,我意識到這是一個XY問題。反思不是我所需要的。 – Bitterblue 2013-11-18 12:08:15

+1

當我將其轉換爲int(.Net 4.5)時,出現此錯誤「類型爲'System.InvalidCastException'的未處理異常」。 – 2014-02-27 16:19:35

+4

並非所有的枚舉都是int!枚舉也可以是sbyte,byte,short,ushort,uint,long,ulong和char。正如接受的答案所暗示的,你應該投下基礎類型。 – 2014-10-17 07:17:42

2

嘗試以下操作:

System.Array enumValues = System.Enum.GetValues(typeof(MyEnum)); 
Type underlyingType = System.Enum.GetUnderlyingType(MyEnum); 

foreach (object enumValue in enumValues) 
    System.Console.WriteLine(String.Format("{0}",Convert.ChangeType(enumValue ,underlyingType))); 
0

只是簡單的。

var value = propertyInfo.GetValue(obj); // this return TestOne or TestTwo 

var enumValue = Convert.ChangeType(value, typeof(int)); // this return 3 or 4 
1

嗨,你有這樣的選擇:

Type typevar = GetType([YourEnum])

然後... ... 您 可以開始使用type.GetEnumValues使用typevar.GetEnumNames返回其名稱和數組名稱值獲得,返回包含值的數組。

-1
System.Type.GetType("Namespace Name" + "." + "Class Name" + "+" + "Enum Name") 

Dim fieldInfos() As System.Reflection.FieldInfo = System.Type.GetType("YourNameSpaceName.TestClass+TestEnum").GetFields 

For Each f As System.Reflection.FieldInfo In fieldInfos 
    If f.IsLiteral Then 
     MsgBox(f.Name & " : " & CType(f.GetValue(Nothing), Integer) & vbCrLf) 
    End If 
Next 

Public Class TestClass 
    Public Enum TestEnum 
     val1 = 20 
     val2 = 30 
    End Enum 
End Class 

這一工程

+0

但它不是C# – 2016-01-15 12:38:13

0

對我來說,這個問題是MyEnum尚未發現因+號從裝配越來越式(2號線):

var dll = System.Reflection.Assembly.LoadFile("pathToDll"); 
Type myEnum = dll.GetType("namespace+MyEnum"); 
System.Array myEnumValues = System.Enum.GetValues(myEnum); 
2

對於您的要求是爲很簡單,因爲人們已經指出了它。只需將枚舉對象轉換爲int,即可獲得枚舉的數值。

int value = (int) TestEnum.TestOne; 

但是,如果需要混用枚舉值| (按位或),例如

var value = TestEnum.TestOne | TestEnum.TestTwo; 

,你希望得到什麼混合降值表示,這裏是你如何能做到這一點(注:這是由打算採取按位operatations的優勢INT值表示枚舉):選擇

首先,在字典中獲取枚舉選項及其值。

var all_options_dic = typeof(TestEnum).GetEnumValues().Cast<object>().ToDictionary(k=>k.ToString(), v=>(int) v); 

過濾字典只返回混合選項。

var filtered = all_options_dic.Where(x => (x.Value & (int) options) != 0).ToDictionary(k=>k.Key, v=>v.Value); 

對你的選擇做任何邏輯。例如打印它們,將它們轉到列表等。:

foreach (var key in filtered.Keys) 
     { 
      Console.WriteLine(key + " = " + filtered[key]); 
     } 

希望這有助於。