vb.net在字符串变量中按名称引用结构中的成员

时间:2017-05-17 22:45:33

标签: vb.net visual-studio structure

我有一个像这样的大型结构(50多个成员):

Public Structure DagDay    
    Public DayDate As Date
    Public DayEcoZone As String
    Public DayOrd As Boolean
    Public DayHelg As Boolean
    Public DayAfton As Boolean
    Public DayEvent As Boolean
    Public DayEventText As String
    Public DayIncVat As Boolean
    Public DayOmsTot As Integer
    Public DayOmsCat1 As Integer
    Public DayOmsCat2 As Integer
    Public DayOmsCat3 As Integer
    .....
End Structure
...
Dim ThisDay as DagDay

现在我试图让一个函数在变量ThisDay中设置任何特定成员的值,但我无法弄清楚如何(否则那么大的选择..案例......)。

Public Function SetValue(ByVal Field As String, ByVal value As VariantType) As Boolean

Select Case Field

            Case "DayDate"
                ThisDay.DayDate = value
            Case "DayEcoZone"
                ThisDay.DayEcoZone = value
            Case "DayOrd"
                ThisDay.DayOrd = value
            Case "DayHelg"
                ThisDay.DayHelg = value
         .....

        End Select

我希望能够做到这样的事情(伪代码):

Public Function SetValue(ByVal Field As String, ByVal value As VariantType) As Boolean

        ThisDay.[Field] = value
        Return True
End Function 

如何使用字符串变量引用结构中的特定成员(字段)?

1 个答案:

答案 0 :(得分:2)

使用反思:

我不知道VB.NET语法,但在C#中就是这样:

static void SetValue(Object parent, Object newFieldValue, String fieldName) {

    FieldInfo field = parent.GetType().GetField( fieldName, BindingFlags.Public | BindingFlags.Instance );
    field.SetValue( parent, newFieldValue );
}

由于fieldName是任意输入,因此您可以使用fieldName来防止错误的nameof()值,以确保始终指定有效的字段名称。

注意我们需要x.GetType()而不是typeof(x),因为我们需要运行时类型,而不是编译时类型(总是Object)。

即使您正在使用值类型struct,也不会应用按值传递语义,因为它被装箱为Object(因此它实际上是通过引用传递的)所以设置一个字段就好像它是class(引用类型)。

用法:

MyStruct value;
value.FieldFoo = "hello";
SetValue( value, "world", nameof(value.FieldBar) );
Assert.AreEqual( "world", value.FieldBar );

我的VB.NET有点生疏,但我想这就是它:

Public Shared Sub SetValue(parentAs Object, newFieldValue As Object, fieldName As String)

    Dim field As FieldInfo = parent.GetType().GetField( fieldName, BindingFlags.Public Or BindingFlags.Instance )
    field.SetValue( parent, newFieldValue )

End Sub

VB.NET现在有NameOf运算符,其运行方式与C#相同。

用法:

Dim value As New MyStruct
value.FieldFoo = "hello"
SetValue( value, "world", NameOf(value.FieldBar) )
Assert.AreEqual( "world", value.FieldBar )