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

これはちょっと大げさですが、全体的にかなりエレガントなソリューションを提供すると思います。使用方法は次のとおりです。

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を入力しなくても済むように を使用していることに注意してください.ItemWidening 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

2 つの「コード」をインポートすると、コードを短縮する Enum のプレフィックスなしで実行できます。

于 2013-12-09T12:03:01.293 に答える
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

これを試して:

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

少なくとも、選択した場合のコーディング量が削減されます。

于 2013-04-16T07:54:51.100 に答える