Получение значений статического поля типа с использованием отражения - PullRequest
8 голосов
/ 02 июня 2009

У меня есть набор статических классов «перечисления», которые я использую для хранения значимых имен переменных для представления бессмысленных значений кода, которые я получаю во входном файле. Вот пример одного.

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

Я хочу написать метод, который будет принимать тип одного из этих статических классов и строковое значение и определять, является ли значение одним из значений статического поля. Я знаю, как получить поля экземпляра для определенного объекта, и я знаю, как получить список статических полей для определенного типа; я не могу понять, как получить значения статического поля без экземпляра. Вот что у меня так далеко.

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

Я предположил, что мог бы сделать классы перечисления нестатическими, просто чтобы я мог создать экземпляр для передачи FieldInfo.GetValue в моем методе проверки. Я бы предпочел, чтобы мой класс был таким, какой я есть.

Я вижу метод с именем GetRawConstantValue. Это выглядит опасно. Это даст мне то, что я ищу? Есть еще идеи?

Ответы [ 2 ]

24 голосов
/ 02 июня 2009

Вызов

field.GetValue(Nothing)

и все будет хорошо. Вам не нужен экземпляр для статических членов.

Я не думаю, GetRawConstantValue - это то, что вы хотите - я бы придерживался кода выше.

3 голосов
/ 02 июня 2009

Глядя на то, что вы пытаетесь сделать в более широком смысле, возможно, это было бы лучше подходит:

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

И затем, используя эту ссылку, вы сможете получить поддержку intellisense, которая точно соответствует поддержке обычного перечисления:
Скрытые возможности VB.NET?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...