【问题标题】:Define String ENUM in VB.Net在 VB.Net 中定义字符串 ENUM
【发布时间】:2012-09-07 05:40:35
【问题描述】:

我正在为我的项目使用窗口应用程序。在某些情况下,我需要定义字符串枚举并在我的项目中使用它。

Dim PersonalInfo As String = "Personal Info"
Dim Contanct As String = "Personal Contanct"

    Public Enum Test
        PersonalInfo
        Contanct
    End Enum

现在我希望该变量 PersonalInfo 和 Contract 的值为“个人信息”和“个人联系”。

如何使用 ENUM 获取此值?或任何其他方式。

提前谢谢...

【问题讨论】:

    标签: vb.net string enums windows-applications


    【解决方案1】:

    对于非整数值,可以改用Structure(或Class)中的Const

    Structure Test
        Const PersonalInfo = "Personal Info"
        Const Contanct = "Personal Contanct"
    End Structure
    

    或在Module 中直接访问,无需Test. 部分:

    Module Test
        Public Const PersonalInfo = "Personal Info"
        Public Const Contanct = "Personal Contanct"
    End Module
    

    在某些情况下,变量名可以用作值:

    Enum Test
        Personal_Info
        Personal_Contanct
    End Enum
    
    Dim PersonalInfo As String = Test.Personal_Info.ToString.Replace("_"c, " "c)
    
    ' or in Visual Studio 2015 and newer:
    Dim Contanct As String = NameOf(Test.Personal_Contanct).Replace("_"c, " "c)
    

    【讨论】:

    • 我喜欢这个而不是类的原因是因为这些枚举永远不会被实例化。它们只是聚集在一个地方的字符串的枚举,然后用点符号在其他地方引用。请注意,我们没有声明此结构的任何实例。它是一个仅用于包含常量的结构。你可以对类做同样的事情。我还看到人们用一个类做只读属性。但这些是字符串常量。所以我们使用 const。
    【解决方案2】:

    你可以创建一个新类型

    ''' <completionlist cref="Test"/>
    Class Test
    
        Private Key As String
    
        Public Shared ReadOnly Contact  As Test = New Test("Personal Contanct")
        Public Shared ReadOnly PersonalInfo As Test = New Test("Personal Info")
    
        Private Sub New(key as String)
            Me.Key = key
        End Sub
    
        Public Overrides Function ToString() As String
            Return Me.Key
        End Function
    End Class
    

    当你使用它时,它有点看起来像一个枚举:

    Sub Main
    
        DoSomething(Test.Contact)
        DoSomething(Test.PersonalInfo)
    
    End Sub
    
    Sub DoSomething(test As Test)
        Console.WriteLine(test.ToString())
    End Sub
    

    输出:

    个人联系
    个人资料

    【讨论】:

    • 结构解决方案(Slai)用 4 行代码完成了同样的事情。
    • @JonHarbour Erm... 不,它没有。它只是使用字符串,所以它不像强类型枚举模式那样类型安全,它不能扩展,你不能添加显式转换。此外,在这种情况下,我认为在模块上使用结构没有意义。
    • 如果您想在Select Case 中比较这样的对象,您应该将Key 设为公开并使用.Key 进行比较。
    【解决方案3】:

    如何使用标记。比如:

    Public Enum MyEnum
    <StringValue("Personal Contact")>Contact
    <StringValue("My PersonalInfo")>PersonalInfo
    End Enum
    

    您必须将 StringValue 属性写为:

    Public Class StringValueAttribute
        Inherits Attribute
    
        Public Property Value As String
        Public Sub New(ByVal val As String)
            Value = val
        End Sub
    
    End Class
    

    把它拿出来:

     Public Function GetEnumByStringValueAttribute(value As String, enumType As Type) As Object
        For Each val As [Enum] In [Enum].GetValues(enumType)
            Dim fi As FieldInfo = enumType.GetField(val.ToString())
            Dim attributes As StringValueAttribute() = DirectCast(fi.GetCustomAttributes(GetType(StringValueAttribute), False), StringValueAttribute())
            Dim attr As StringValueAttribute = attributes(0)
            If attr.Value = value Then
                Return val
            End If
        Next
        Throw New ArgumentException("The value '" & value & "' is not supported.")
    End Function
    
    Public Function GetEnumByStringValueAttribute(Of YourEnumType)(value As String) As YourEnumType
        Return CType(GetEnumByStringValueAttribute(value, GetType(YourEnumType)), YourEnumType)
    End Function
    

    然后调用获取枚举(使用字符串属性):

    Dim mEnum as MyEnum = GetEnumByStringValueAttribute(Of MyEnum)("Personal Contact")
    

    要获取“属性”值(为了清楚起见,删除了处理“无”):

      Public Function GetEnumValue(Of YourEnumType)(p As YourEnumType) As String
            Return DirectCast(Attribute.GetCustomAttribute(ForValue(p), GetType(StringValueAttribute)), StringValueAttribute).Value
      End Function
    
      Private Function ForValue(Of YourEnumType)(p As YourEnumType) As MemberInfo
            Return GetType(YourEnumType).GetField([Enum].GetName(GetType(YourEnumType), p))
      End Function
    

    以及获取字符串属性的调用(使用Enum):

    Dim strValue as String = GetEnumValue(Of MyEnum)(MyEnum.Contact)
    

    【讨论】:

    • 如何获取字符串常量?
    • 对于字符串枚举来说太复杂了。
    • 它可能看起来令人费解,但我认为这是最好的解决方案恕我直言。就我而言,我真的希望它在比较过程中像 Enum 一样工作。 (例如:如果 myValue = Test.PersonalInfo...)。
    • @Jon,这取决于你怎么做。我介绍了处理属性的方法。如果你有它作为一个帮助类,你可以在任何地方使用标记,它变得非常有用,特别是如果你在 C# 中处理过 Enums 并且喜欢该功能 - 遗憾的是 VB.NET Enums 缺少 C# 功能..
    【解决方案4】:

    如何使用 ENUM 获取此值?或任何其他方式。

    将枚举值映射到字符串的常用方法有以下三种:

    • 使用Dictionary(Of YourEnumType, String)
    • 用属性(例如DescriptionAttribute)装饰枚举值并通过反射获取它们
    • 使用Switch 语句

    在我看来,这些选项中的第一个可能是最简单的。

    【讨论】:

    • 谢谢乔恩。实际上我是 Windows 应用程序的新手。你能给我简单介绍一下第一种方式吗(字典..)?
    • @BrijeshPatel:Stack Overflow 并不是从头开始学习的好方法。我建议您阅读Dictionary 文档,最好阅读一本包含集合的好 VB 书籍。
    【解决方案5】:

    我知道这是一篇旧帖子,我找到了一个值得分享的好解决方案:

    ''' <summary>
    ''' Gives acces to strings paths that are used often in the application
    ''' </summary>
    Public NotInheritable Class Link        
        Public Const lrAutoSpeed As String          = "scVirtualMaster<.lrAutoSpeed>"
        Public Const eSimpleStatus As String        = "scMachineControl<.eSimpleStatus>"
        Public Const xLivebitHMI As String          = "scMachineControl<.xLivebitHMI>"      
        Public Const xChangeCycleActive As String   = "scMachineControl<.xChangeCycleActive>"
    
    End Class
    

    用法:

    'Can be anywhere in you applicaiton:
    Link.xChangeCycleActive
    

    这可以防止不必要的额外编码,易于维护,我认为这可以最大限度地减少额外的处理器开销。

    Visual Studio 还会在您键入“链接”后立即显示字符串属性 就像它是一个普通的枚举一样

    【讨论】:

    • 第一个 const 的返回值是多少? “scVirtualMaster”或“<.lrautospeed>”
    • 它返回完整的字符串,所以:scVirtualMaster<.lrautospeed>
    【解决方案6】:

    如果您只想在列表或组合中显示枚举,则可以使用标记,例如

    Private Enum MyEnum
        Select_an_option___
        __ACCOUNTS__
        Invoices0
        Review_Invoice
        __MEETINGS__
        Scheduled_Meetings0
        Open_Meeting
        Cancelled_Meetings0
        Current_Meetings0
    End Enum
    

    然后将MyEnum拉成一个字符串并使用Replace(或Regex)替换标签:“___”为“...”,“__”为“**”,“_”与“”,并删除尾随数字。然后将其重新打包成一个数组并将其转储到一个组合框中,如下所示:

    Select an option...
    **ACCOUNTS**
    Invoices
    Review Invoice
    **MEETINGS**
    Scheduled Meetings
    Open Meeting
    Cancelled Meetings
    Current Meetings
    

    (例如,您可以使用这些数字来禁用用于输入发票编号或会议室的文本字段。在示例中,Review InvoiceOpen Meeting 可能需要额外的输入,因此可能会启用文本框这些选择。)

    当您解析选定的组合项时,枚举将按预期工作,但您只需要添加一行代码 - 文本替换 - 即可使组合看起来如您所愿。

    (解释的内容大约是实际解决方案的10倍!)

    【讨论】:

      【解决方案7】:

      来自微软的这种技术 - “How to: Determine the String Associated with an Enumeration Value (Visual Basic)” - 在某些情况下会很有用(不幸的是它对我没有帮助:()。微软的例子:

      VB:

      Public Enum flavorEnum
          salty
          sweet
          sour
          bitter
      End Enum
      
      Private Sub TestMethod()
          MsgBox("The strings in the flavorEnum are:")
          Dim i As String
          For Each i In [Enum].GetNames(GetType(flavorEnum))
              MsgBox(i)
          Next
      End Sub
      

      【讨论】:

        猜你喜欢
        • 2022-12-07
        • 2011-01-18
        • 2012-05-02
        • 2017-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-01-15
        • 2018-10-18
        相关资源
        最近更新 更多