2009-06-02 21 views
8

Mam zestaw statycznych klas "wyliczeniowych", których używam do przechowywania znaczących nazw zmiennych w celu przedstawienia bezsensownych wartości kodu, które otrzymuję na pliku wejściowym. Oto przykład jednego.Uzyskiwanie wartości pól statycznych typu za pomocą refleksji

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

Chcę napisać metodę, która będzie akceptować typ jednej z tych klas statycznych i wartość ciągu i ustalić, czy wartość jest jedną z wartości pól statycznych. Wiem, jak uzyskać pola instancji dla określonego obiektu i wiem, jak uzyskać listę pól statycznych dla określonego typu; nie mogę się dowiedzieć, jak uzyskać wartości pól statycznych bez instancji. Oto, co mam do tej pory.

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 

mam mogę zrobić klasy wyliczeniowe niestatyczny tylko tak mogę utworzyć instancję przekazać do FieldInfo.GetValue wewnątrz mojej metody walidacji. Wolałbym, żeby moja klasa była taka, jak to możliwe.

Widzę metodę o nazwie GetRawConstantValue. Wygląda niebezpiecznie. Czy to da mi to, czego szukam? Jakieś inne pomysły?

Odpowiedz

24

połączeń

field.GetValue(Nothing) 

i to będzie w porządku. Nie potrzebujesz instancji dla statycznych członków.

Ja nie Myślę, żeGetRawConstantValue jest to, czego chcesz - trzymałbym się powyższego kodu.

+1

Hej, umieścisz go w VB dla mnie. Nigdy nie myślałem o przekazaniu wartości zerowej. Dzięki. –

+0

Zadaj pytanie w VB, a spróbuję odpowiedzieć na to w VB. Czasami źle idzie, ale w tym przypadku nie było to zbyt trudne :) –

+13

Kolejny fakt JS: Jon Skeet oblicza swoje odpowiedzi w uniwersalnym IL, a następnie tłumaczy na odpowiedni kod źródłowy ... –

3

Patrząc na to, co próbujemy zrobić w szerszym sensie, być może byłoby to lepsze dopasowanie:

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 

A następnie za pomocą tego linku może być w stanie uzyskać intellisense wsparcie, które dokładnie odpowiada, że z normalnego wyliczenia:
Hidden Features of VB.NET?

+0

Joel, to jest dokładna odpowiedź, której szukam na pytanie 935544 (i bardzo dobra odpowiedź również dla obecnego pytania). Jeśli mógłbyś odpowiedzieć na to pytanie linkiem do tej odpowiedzi, byłoby to pomocne. Dzięki za dodatkowe informacje. Link do ukrytych funkcji jest doskonały. –

+0

wszystko gotowe. –

Powiązane problemy