这有点夸张,但我认为它总体上提供了一个非常优雅的解决方案。这是它的使用方式:
Public Class ConstantsExample
Public Sub UseConstant()
Dim value As String = Constants.Types(TypeA)
Dim category As String = Constants.Categories(General)
End Sub
End Class
如您所见,使用它的代码尽可能短。它确实依赖于一大堆源代码:
Public Enum TypeCodes
<Description("Type A")> TypeA = 0
<Description("Type B")> TypeB
<Description("Type C")> TypeC
End Enum
Public Enum CategoryCodes
<Description("General")> General = 0
<Description("Specific")> Specific
<Description("Other")> Other
End Enum
Public NotInheritable Class Constants
#Region "Resources"
Private Shared myTypes As Dictionary(Of TypeCodes, ConstantItem) = Nothing
Public Shared ReadOnly Property Types() As Dictionary(Of TypeCodes, ConstantItem)
Get
If myTypes Is Nothing Then
myTypes = New Dictionary(Of TypeCodes, ConstantItem)
BuildTypes(myTypes)
End If
Return myTypes
End Get
End Property
Private Shared Sub BuildTypes(ByRef dict As Dictionary(Of TypeCodes, ConstantItem))
With dict
.Add(TypeCodes.TypeA, New ConstantItem(TypeCodes.TypeA.Description, "Type A are..."))
.Add(TypeCodes.TypeB, New ConstantItem(TypeCodes.TypeB.Description, "Type B are..."))
.Add(TypeCodes.TypeC, New ConstantItem(TypeCodes.TypeC.Description, "Type C are..."))
End With
End Sub
#End Region
#Region "Categories"
Private Shared myCategories As Dictionary(Of CategoryCodes, ConstantItem) = Nothing
Public Shared ReadOnly Property Categories() As Dictionary(Of CategoryCodes, ConstantItem)
Get
If myCategories Is Nothing Then
myCategories = New Dictionary(Of CategoryCodes, ConstantItem)
BuildCategories(myCategories)
End If
Return myCategories
End Get
End Property
Private Shared Sub BuildCategories(ByRef dict As Dictionary(Of CategoryCodes, ConstantItem))
With dict
.Add(CategoryCodes.General, New ConstantItem(CategoryCodes.General.Description, "General category"))
.Add(CategoryCodes.Specific, New ConstantItem(CategoryCodes.Specific.Description, "Specific category"))
.Add(CategoryCodes.Other, New ConstantItem(CategoryCodes.Other.Description, "Other category"))
End With
End Sub
#End Region
End Class
Public NotInheritable Class ConstantItem
#Region "Constructors"
''' <summary>
''' Default constructor.
''' </summary>
Public Sub New()
'Do nothing
End Sub
''' <summary>
''' Simple constructor.
''' </summary>
Sub New(value As String)
Me.Name = value
Me.Description = value
End Sub
''' <summary>
''' Proper constructor.
''' </summary>
Sub New(name As String, description As String)
Me.Name = name
Me.Description = description
End Sub
#End Region
Property Name As String
Property Description As String
''' <summary>
''' See http://stackoverflow.com/questions/293215/default-properties-in-vb-net
''' </summary>
Public Shared Widening Operator CType(value As String) As ConstantItem
Return New ConstantItem(value)
End Operator
''' <summary>
''' See http://stackoverflow.com/questions/293215/default-properties-in-vb-net
''' </summary>
Public Shared Widening Operator CType(value As ConstantItem) As String
Return value.Name
End Operator
End Class
注意使用Widening Operator
to 不必键入.Item
。如果您不想使用Widening Operator
那么简单的注释并更改Constants.Types(TypeA)
为Constants.Types.Item(TypeA)
.
这是您可能需要的描述扩展:
Public Module Extensions
Private Enum SampleDescription
<Description("Item One")> ItemOne = 1
<Description("Item Two")> ItemTwo = 2
<Description("Item Three has a long description")> ItemThree = 3
End Enum
''' <summary>
''' This procedure gets the description attribute of an enum constant, if any. Otherwise it gets
''' the string name of the enum member.
''' </summary>
''' <param name="value"></param>
''' <returns></returns>
''' <remarks>Usage: myenum.Member.Description()
''' Add the Description attribute to each member of the enumeration.</remarks>
<Extension()> _
Public Function Description(ByVal value As [Enum]) As String
Dim fi As Reflection.FieldInfo = value.GetType().GetField(value.ToString())
Dim aattr() As DescriptionAttribute = DirectCast(fi.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute())
If aattr.Length > 0 Then
Return aattr(0).Description
Else
Return value.ToString()
End If
End Function
End Module
这些是我使用的 Imports 语句(程序集称为 MyPatterns):
Imports System.ComponentModel
Imports MyPatterns.TypeCodes
Imports MyPatterns.CategoryCodes
导入这两个“代码”允许您在没有缩短代码的 Enum 前缀的情况下进行操作。