3

的動態值,如果有有常量的定義如下:VB.NET:獲取常量

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 

根名稱與cons的名稱匹配坦。從字典中獲得一個項目的價值,我可以用這樣的:

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)) 

感謝您的任何迴應。

+1

請參閱http://stackoverflow.com/questions/1456518/how-to-obtain-a-list-of-constants-in-a-class-and-their-values?rq=1瞭解如何獲取常量及其值的列表。然後,請參閱http://stackoverflow.com/questions/1308507/reflecting-constant-properties-fields-in-net/1308604#1308604,以獲取查找常量的更簡潔的示例。另一方面,你真的需要它們是單獨的常量嗎?你可以跳過常數,只用字典嗎? – Abraham

+0

我可以在兩個鏈接的幫助下解決它。謝謝。我使用的常量,因爲該進程分爲兩個程序集。常量定義和字典分析包含在一個MustInherit類中,在另一個程序集中,這個類被繼承並且字典被填充值。爲了避免多次寫入這些值,我使用了這些常量。 – mburm

回答

2

@Clara野驢

我的解決方案我所用的是以下

Me.GetType.GetField(
    "Xsl", 
    Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static Or System.Reflection.BindingFlags.FlattenHierarchy 
).GetValue(Nothing) 
2

試試這個:

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

至少會降低在選擇情況下的編碼量。

+0

感謝您的回覆。這是一個有效的解決方案,但@Abraham的提示讓我更加優雅的實現。 – mburm

+1

@mburm爲什麼不把你更優雅的解決方案作爲公認的答案來添加,並照亮我們所有人? –

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的與具有輸入.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 

而且這些都是進口的語句我用(大會被稱爲MyPatterns):

Imports System.ComponentModel 
Imports MyPatterns.TypeCodes 
Imports MyPatterns.CategoryCodes 

導入兩個「規範」允許你沒有爲縮短代碼的Enum添加前綴。