2009-06-02 2 views
8

ho un set di statici "enumerazione" classi che sto usando per tenere i nomi delle variabili significative per rappresentare i valori di codice senza senso che ricevo su un file di input. Ecco un esempio di uno.Come valori dei campi statici di tipo utilizzando riflessione

Public Class ReasonCodeValue 
    Private Sub New() 
    End Sub 
    Public Shared ReadOnly ServiceNotCovered As String = "SNCV" 
    Public Shared ReadOnly MemberNotEligible As String = "MNEL" 
End Class 

Voglio scrivere un metodo che accettare il tipo di una di queste classi statiche e un valore di stringa e determinare se il valore è uno dei valori di campo statici. So come ottenere i campi di istanza di un oggetto specifico, e so come ottenere un elenco di campi statici per un tipo specifico; quello che non riesco a capire è come ottenere i valori dei campi statici senza un'istanza. Ecco cosa ho ottenuto finora.

Public Function IsValidValue(ByVal type As Type, ByVal value As String) As Boolean 
    Dim fields = type.GetFields(BindingFlags.Public Or BindingFlags.Static) 
    For Each field As FieldInfo In fields 
     DoSomething() 
    Next 
End Function 

dovrei avrei potuto fare le classi di enumerazione non statico solo così posso creare un'istanza di passare alla FieldInfo.GetValue dentro il mio metodo di convalida. Preferirei mantenere la mia classe così com'è, se posso.

vedo un metodo chiamato GetRawConstantValue. Sembra pericoloso Questo mi darà quello che sto cercando? Altre idee?

risposta

24

chiamata

field.GetValue(Nothing) 

e andrà tutto bene. Non hai bisogno di un'istanza per i membri statici.

Io non pensoGetRawConstantValue è quello che vuoi - io rispetterei il codice sopra.

+1

Ehi, lo metti in VB per me. Mai pensato di passare un nulla. Grazie. –

+0

Fai una domanda a VB e cercherò di rispondere in VB. A volte va male male, ma in questo caso non è stato troppo difficile :) –

+13

Un altro fatto JS: Jon Skeet calcola le sue risposte in un IL universale e quindi traduce il codice sorgente appropriata ... –

3

Guardando a quello che si sta cercando di fare in senso più ampio, forse questo sarebbe una misura migliore:

Public Interface ICustomEnum(Of T) 
    Function FromT(ByVal value As T) As ICustomEnum(Of T) 
    ReadOnly Property Value() As T 

    ''// Implement using a private constructor that accepts and sets the Value property, 
    ''// one shared readonly property for each desired value in the enum, 
    ''// and widening conversions to and from T. 
    ''// Then see this link to get intellisense support 
    ''// that exactly matches a normal enum: 
    ''// https://stackoverflow.com/questions/102084/hidden-features-of-vb-net/102217#102217 
End Interface 

' 
''' <completionlist cref="ReasonCodeValue"/> 
Public NotInheritable Class ReasonCodeValue 
    Implements ICustomEnum(Of String) 

    Private _value As String 
    Public ReadOnly Property Value() As String Implements ICustomEnum(Of String).Value 
     Get 
      Return _value 
     End Get 
    End Property 

    Private Sub New(ByVal value As String) 
     _value = value 
    End Sub 

    Private Shared _ServiceNotCovered As New ReasonCodeValue("SNCV") 
    Public Shared ReadOnly Property ServiceNotCovered() As ReasonCodeValue 
     Get 
      Return _ServiceNotCovered 
     End Get 
    End Property 

    Private Shared _MemberNotEligible As New ReasonCodeValue("MNEL") 
    Public Shared ReadOnly Property MemberNotEligible() As ReasonCodeValue 
     Get 
      Return _MemberNotEligible 
     End Get 
    End Property 

    Public Shared Function FromString(ByVal value As String) As ICustomEnum(Of String) 
     ''// use reflection or a dictionary here if you have a lot of values 
     Select Case value 
      Case "SNCV" 
       Return _ServiceNotCovered 
      Case "MNEL" 
       Return _MemberNotEligible 
      Case Else 
       Return Nothing ''//or throw an exception 
     End Select 
    End Function 

    Public Function FromT(ByVal value As String) As ICustomEnum(Of String) Implements ICustomEnum(Of String).FromT 
     Return FromString(value) 
    End Function 

    Public Shared Widening Operator CType(ByVal item As ReasonCodeValue) As String 
     Return item.Value 
    End Operator 

    Public Shared Widening Operator CType(ByVal value As String) As ReasonCodeValue 
     Return FromString(value) 
    End Operator 
End Class 

E quindi utilizzando questo link potrebbe essere in grado di ottenere il supporto IntelliSense che corrisponde esattamente quello di un normale enum:
Hidden Features of VB.NET?

+0

Joel, questo è il risposta esatta che sto cercando per la domanda 935544 (e un'ottima risposta anche per la domanda corrente). Se potessi rispondere a questa domanda con un link a questa risposta, sarebbe utile. Grazie per le informazioni extra. Il collegamento delle funzionalità nascoste è eccellente. –

+0

tutto fatto. –