【问题标题】:vb.net Reference a member in a structure by name from string-variablevb.net 通过字符串变量的名称引用结构中的成员
【发布时间】:2017-05-18 06:54:49
【问题描述】:

我有一个像这样的大型结构(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 

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

【问题讨论】:

  • VariantType 是什么?
  • @Plutonix,我认为这是对 Microsoft.VisualBasic.VariantType 枚举的滥用。
  • 你从哪里得到你传入的Field 的值?
  • @Enigmativity,Field 的值来自相应输入字段的名称属性(TextBoxCheckBox):在三个不同@ 之一中动态创建的es-控件987654330@.

标签: vb.net visual-studio structure


【解决方案1】:

使用反射:

我不知道 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 是任意输入,您可以通过使用nameof() 来防止不正确的fieldName 值,以确保您始终指定有效的字段名称。

请注意,我们需要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 )

【讨论】:

  • 感谢一百万的快速和出色的回答,现在测试一下。
  • 像魅力一样工作!很好的解释!只需要一个“Imports System.Reflection”。谢谢!!!
猜你喜欢
  • 1970-01-01
  • 2016-11-14
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 2022-12-17
  • 2023-03-17
  • 1970-01-01
  • 2022-01-22
相关资源
最近更新 更多