【问题标题】:How to refer to an enum by it's string name?如何通过字符串名称引用枚举?
【发布时间】:2012-11-23 04:42:40
【问题描述】:

我想通过根的字符串名称来引用枚举。请注意,我希望引用枚举,而不是枚举成员。

stackoverflow 上有很多帖子描述了如何通过名称来引用枚举成员(例如 How to retrieve an Enum member given its name),但我没有找到任何关于如何通过根名称来引用枚举的信息。

进一步澄清;

Enum MyEnumA : Quiet : Noisy : End enum
Enum MyEnumB : Big : Small : Gigantic : End enum

Sub Foo(strAction as string)
    ' Depending on value of strAction, i want to create a list of either MyEnumA or MyEnumB members
    ' I know i can't do the following, it's just to make clear the direction i'm wanting to go -
    Dim lstMembers As New List(Of CType(strAction,[Enum]))   
    '....
end function

按照下面的好建议,我已经尝试过了;

Dim enumType As Type = System.Type.GetType("ExcelInterface.clsBTAnalyseRslts+" & "strAction")
Dim lstFldIndx As New List(Of enumtype)   'Fails to compile this line as doesn't recognize enumtype as defined

谢谢!

【问题讨论】:

  • 您的清单中究竟想要什么? “EnumXXX”中每个值的名称,或“EnumXXX”的每个值。在第一种情况下,您将有一个 List(Of String) 和一个 List(Of Integer) 用于第二种情况。
  • 看来是这样。不是出于恶意,而不仅仅是不了解系统。感谢您指出 - 将寻求纠正。

标签: vb.net types enums


【解决方案1】:

试一试,它会创建一个数组,以便您稍后将其更改为 List(Of x...):

Sub Foo(ByVal strAction As String)

    Dim exAssembly = Reflection.Assembly.GetExecutingAssembly

    Dim enumType = exAssembly.GetTypes.First(Function(f) f.Name = strAction)

    Dim myEnum = [Enum].GetValues(enumType)

End Sub

我发现了一个有趣的帖子here,它给了我一些方向。

用法:

Foo("MyEnumA")

我会让你做一些错误处理和检查:D

【讨论】:

  • 这几乎可以让我到达那里,但我无法让它发挥作用。这有效: Dim enumType As Type = Reflection.Assembly.GetExecutingAssembly.GetTypes.First(Function(f) f.Name = "Fname") 但如果我执行 List(of EnumType) 或执行 GetType,则会出现编译错误(枚举类型)。错误说 EnumType 没有定义,显然不是这样。
  • 保持函数原样,在最后一行,Dim myEnum = [Enum].GetValues(enumType),在其下方放置一个 for each 循环,并将 myEnum 中的每个项目放入一个列表(Of字符串)
【解决方案2】:

这是一个代码块,它将枚举转换为字符串,然后根据字符串获取类型。它将向您展示如何获取类型以及如何格式化字符串。其余的应该很简单。

Dim obj As MyEnumA
Dim t As Type = obj.GetType()
Dim s As String = t.FullName
Dim t2 As Type = System.Type.GetType(s)

然后执行此操作以获取值:

Dim Members() As String
Members = System.Enum.GetNames(t2)

变量 s 看起来像这样“namespace.class + MyEnumA”,所以您需要做的就是以编程方式创建此字符串并将其发送到函数。

【讨论】:

  • 我相信 OP 想要传递一个字符串,例如“MyEnumA”或任何其他枚举作为字符串,然后从枚举的每个成员中获取值。不过我可能是错的
  • 我同意。对于 OPs 问题的解决方案,您只需使用最后一行:Dim t2 as Type = System.Type.GetType(strAction)。但要使其正常工作,strAction 必须是前三行提供的 Enum 类型的确切名称。他现在需要做的就是获取名称,查看它,然后从中创建他的字符串。他在最终解决方案中不需要 1-3 行,这只是途中的帮助。
  • 试试我的解决方案:创建一个枚举,复制我的函数并在调试器中查看结果。您应该能够在 Dim myEnum = .... 行上看到枚举成员
  • 哦,它有效,不要误会我的意思,我并不是说你的解决方案不好。我刚刚发现该解决方案看起来过于复杂 :) 但是您获得了额外的功劳,因为您的解决方案实际上是在使用“MyEnumA”,而我​​的函数需要“namespace.class+MyEnumA”。
  • @WozzeC 谢谢你的建议。我确实尝试过它并且类似于 Ric 的建议,由于某种原因它无法识别 t2(或 EnumType)。例如我可以做GetType(MyEnumA) 但我不能做GetType(t2)。类似地创建一个列表。
【解决方案3】:

Ric 的回答不太适合我,因为我的 Enum 与我的代码不在同一个位置,所以这就是我最终管理它的方式(我使用 VB,但我会添加 C# 以供参考):

VB

Dim EnumName As String = "MyEnum"
Dim MyAssembly As System.Reflection.Assembly = System.Reflection.Assembly.GetAssembly(GetType(My.Assembly.Location))
Dim MyEnum As System.Type = MyAssembly.GetType("My.Assembly.Location+ClassName+" & EnumName)
Dim EnumNames As String() = MyEnum.GetEnumNames()
For intVal As Integer = 0 To EnumNames.Length - 1
    ' EnumNames(intVal) = Name of Enum Value
    ' intVal = Enum Value
Next

C#

string EnumName = "MyEnum";
System.Reflection.Assembly MyAssembly = System.Reflection.Assembly.GetAssembly(typeof(My.Assembly.Location));
System.Type MyEnum = MyAssembly.GetType("My.Assembly.Location+ClassName+" + EnumName);
string[] EnumNames = MyEnum.GetEnumNames();
for (int intVal = 0; intVal <= EnumNames.Length - 1; intVal++) {
    // EnumNames(intVal) = Name of Enum Value
    // intVal = Enum Value
}

希望它能节省一些人的宝贵时间:)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-13
    • 1970-01-01
    • 2010-09-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多