2009-06-02 38 views
8

Tôi đã có một tập các lớp "liệt kê" tĩnh mà tôi đang sử dụng để giữ các tên biến có ý nghĩa đại diện cho các giá trị mã vô nghĩa mà tôi nhận được trên tệp đầu vào. Đây là một ví dụ về một.Lấy các giá trị trường tĩnh của một kiểu bằng cách sử dụng sự phản chiếu

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

Tôi muốn viết một phương pháp mà sẽ chấp nhận loại của một trong những lớp học tĩnh và một giá trị chuỗi và xác định xem giá trị là một trong những giá trị trường tĩnh. Tôi biết làm thế nào để có được các lĩnh vực thể hiện cho một đối tượng cụ thể, và tôi biết làm thế nào để có được một danh sách các lĩnh vực tĩnh cho một loại hình cụ thể; những gì tôi không thể tìm ra là làm thế nào để có được các giá trị trường tĩnh mà không có một cá thể. Đây là những gì tôi đã có cho đến nay.

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 

Tôi nghĩ tôi có thể làm cho các lớp liệt kê không tĩnh chỉ để tôi có thể tạo ra một thể hiện để vượt qua để FieldInfo.GetValue bên trong phương pháp xác nhận của tôi. Tôi muốn giữ cho lớp của tôi theo cách của nó nếu tôi có thể.

Tôi thấy phương thức có tên là GetRawConstantValue. Có vẻ nguy hiểm. Điều đó sẽ cho tôi những gì tôi đang tìm kiếm? Bất kỳ ý tưởng nào khác?

Trả lời

24

Gọi

field.GetValue(Nothing) 

và nó sẽ ổn thôi. Bạn không cần một cá thể cho các thành viên tĩnh.

Tôi không nghĩGetRawConstantValue là những gì bạn muốn - Tôi muốn gắn mã ở trên.

+1

Hey, bạn đặt nó trong VB cho tôi. Không bao giờ nghĩ đến việc vượt qua một null. Cảm ơn. –

+0

Đặt câu hỏi trong VB và tôi sẽ cố gắng trả lời câu hỏi đó trong VB. Đôi khi nó đi sai, nhưng trong trường hợp này nó không quá khó :) –

+13

Một thực tế JS: Jon Skeet tính câu trả lời của mình trong một IL phổ quát và sau đó dịch nó sang mã nguồn thích hợp ... –

3

Nhìn vào những gì bạn đang cố gắng làm theo ý nghĩa lớn hơn, có lẽ đây sẽ là một sự phù hợp tốt hơn:

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 

Và sau đó sử dụng liên kết này, bạn có thể có thể nhận được hỗ trợ IntelliSense mà chính xác khớp với của một enum bình thường:
Hidden Features of VB.NET?

+0

Joel, đây là câu trả lời chính xác tôi đang tìm kiếm trên câu hỏi 935544 (và một câu trả lời rất tốt cho câu hỏi hiện tại quá). Nếu bạn có thể trả lời câu hỏi đó bằng một liên kết đến câu trả lời này, điều đó sẽ hữu ích. Cảm ơn bạn đã cung cấp thêm thông tin. Các tính năng ẩn liên kết là tuyệt vời. –

+0

đã xong. –

Các vấn đề liên quan