2012-09-07 17 views
20

私のプロジェクトではWindow Applicationを使用しています。私は文字列の列挙を定義し、私のプロジェクトでそれを使用する必要がある状況があります。VB.Netで文字列ENUMを定義する

すなわち

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

    Public Enum Test 
     PersonalInfo 
     Contanct 
    End Enum 

今私は、「個人情報」と「個人Contanct」としてその変数PersonalInfoとの契約の値を求めています。

ENUMを使用してこの値を取得するにはどうすればよいですか?またはそれを行うための他の方法。事前に

おかげで...

答えて

18

あなただけの新しいタイプ

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

出力:

個人Contanct
個人情報

+1

構造ソリューション(Slaiによる)は、4行のコードで同じことを達成します。 –

+0

@JonHarbour Erm ...いいえ、そうではありません。文字列を使用するだけなので、厳密に型指定されたenumパターンと同じ型セーフではなく、拡張することもできず、明示的な変換を追加することもできません。また、この場合、モジュール上で構造体を使用する際のポイントがありません。 – sloth

+0

このようなオブジェクトを 'Select Case'で比較したい場合は' Key'を公開し、 '.Key'を使って比較してください。 – mbomb007

5

は、どのように私はENUMを使用して、この値を得ることができますか?またはそれを行うための他の方法。

文字列へのマッピング列挙値の3つの一般的な方法があります。

属性(例えば DescriptionAttribute)と列挙値を飾ると反射
  • 使用してAとそれらをフェッチDictionary(Of YourEnumType, String)
  • を使用
    • Switchステートメント

    これらのオプションの最初のものはおそらく私の考えでは、最も単純です。

  • +1

    ありがとうございました。実際に私はWindowsアプリケーションでは新しいです。あなたは私に最初のやり方(辞書..)でもっと簡単なことを教えてくれますか? –

    +6

    @BrijeshPatel:Stack Overflowは実際にはゼロから学習する良い方法ではありません。 'Dictionary'のドキュメントを読むことをお勧めします。コレクションを扱うべきVBの本を読んでください。 –

    +1

    Ohh ok。しかし、とにかくあなたの貴重な提案に感謝します。 –

    4

    タグ付けの使用はいかがですか。それを取得するには

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

    :あなたのようにSTRINGVALUE属性を記述する必要があります

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

    :ような何か

    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 
    

    と(列挙型を使用して)文字列の属性を取得するためのコール:

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

    どのように文字列定数を取得できますか? –

    +0

    @マハーン - 上記のコードに追加 – Denis

    +1

    あまりにも文字列の列挙のために複雑すぎる方法。 –

    35

    Structure Test 
        Const PersonalInfo = "Personal Info" 
        Const Contanct = "Personal Contanct" 
    End Structure 
    
    Structure(又は Class)を代わりに使用することができ、非整数値、 Const

    またはTest.一部せずに直接アクセスするための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) 
    
    +2

    私が好きな理由これは、これらの列挙がインスタンス化されることは決してないためです。それらは、単一の場所に集められた文字列の単なる列挙であり、ドット表記で別の場所で参照されます。ここでは、この構造体のインスタンスは宣言していません。定数を格納する目的のための構造体です。あなたはクラスで同じことをすることができます。私はまた、人々がクラスで読み込み専用のプロパティを参照するのを見たことがあります。しかし、これらは文字列定数です。だから我々はconstを使う。 –

    2

    :いくつかのケースでは

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

    、変数名を値として使用することができます古い記事を投稿すると、分かち合う価値のある素晴らしいソリューションが見つかりました:

    ''' <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は、あなたがちょうどあなたがしたいすべてはあなたが使用することができ、リストまたはコンボで列挙型を表示している場合、それは定期的に列挙

    +0

    最初のconstの戻り値は何ですか? "scVirtualMaster"または "<.lrAutoSpeed>" – RonaldPaguay

    +0

    完全な文字列を返します。scVirtualMaster <.lrAutoSpeed> –

    0

    である場合のように、「リンク」 入力した直後に、文字列の属性を示していそして、文字列にMyEnumを引くとタグを置き換えるためにReplace(またはRegex)を使用して、このような

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

    としてタグ付け: "___" と "..."、 "__" "**"、「_と""で終わり、末尾の数字を削除します。その後、配列にそれを再梱包してのようになりますコンボボックスにそれをダンプ:

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

    (あなたは、請求書番号や会議室を入力するためのテキストフィールドを無効にし、たとえば、に番号を使用することができますで。たとえば、Review InvoiceOpen Meetingは追加入力が必要なため、これらの選択肢に対してテキストボックスが有効になっている可能性があります。)

    選択したコンボアイテムを解析すると、列挙は期待どおりに機能しますが、コンボを希望通りに表示するには、実際には1行のコード(テキスト置換)を追加する必要があります。

    (説明は実際のソリューションの約10倍です)

    関連する問題