3

如果有以下常量定义:

Protected Const Xsl As String = "Configuration.Xsl"
Protected Const Form As String = "Settings.Form"
Protected Const Ascx As String = "Implementation.Ascx"
...

为了填充字典,我使用这个常量作为键:

MyDictionary.Add(Converter.Xsl, "Item 1")
MyDictionary.Add(Converter.Form, "Item 2")
MyDictionary.Add(Converter.Ascx, "Item 3")
...

现在我通过一个 XML 文件循环运行并提取根节点的名称:

Dim document As New XmlDocument
document.Load(File.FullName)

Dim rootName As String = document.DocumentElement.Name

根名称与常量的名称相匹配。要从字典中获取项目的值,我可以使用如下内容:

Select Case rootName.ToUpper
    Case "Xsl".ToUpper
        DictionaryValue = MyDictionary(Class.Xsl)
    Case "Form".ToUpper
        DictionaryValue = MyDictionary(Class.Form)
    Case "Ascx".ToUpper
        DictionaryValue = MyDictionary(Class.Ascx)
    ...
    Case Else
End Select

如果添加或删除常量,我还必须更改选择。有没有另一种方法来获取常量的值?就像是

DictionaryValue = MyDictionary(SomeFunctionToGetConstantValue(rootName))

感谢您的任何回复。

4

3 回答 3

2

尝试这个:

For Each sKey As String In MyDictionary.Keys
    If rootName.Equals(sKey, StringComparison.CurrentCultureIgnoreCase) Then
        DictionaryValue = MyDictionary(sKey)
        Exit For
    End If
Next

至少它会减少 select 情况下的编码量。

于 2013-04-16T07:54:51.100 回答
2

@克拉拉·奥纳格

我使用的解决方案如下

Me.GetType.GetField(
    "Xsl",
    Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static Or System.Reflection.BindingFlags.FlattenHierarchy
).GetValue(Nothing)
于 2013-12-05T09:03:07.030 回答
2

这有点夸张,但我认为它总体上提供了一个非常优雅的解决方案。这是它的使用方式:

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 Operatorto 不必键入.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 前缀的情况下进行操作。

于 2013-12-09T12:03:01.293 回答