VB.NET遍历结构对象

4

我有一个名为“xyz”的结构,其中包含3个字符串对象。它们分别是“foo”、“bar”和“abc”。我想遍历该结构并比较对象的名称。

Structure xyz
    dim foo as string
    dim bar as string
    dim abc as string
End Structure

伪类:

For each x as object in xyz 
    if x.Name = "foo" then
        'bang
    end if
End each

这是可能的吗?


3
这是可能的,但通常不建议这样做。相反,这往往是设计上的缺陷。告诉我们您为什么需要这样做,以便我们能够给出最佳建议。 - Konrad Rudolph
1
Konrad是正确的。您可以使用反射来获取此信息,但这将影响性能。 - Shawn Steward
2
为什么不直接使用字典呢? - Shawn Steward
2
“这只是一次性的事情”——开发人员的臭名昭著的遗言。 - George Johnston
请记住,如果您愿意,可以使用 dict!foo 语法。 - Mark Hurd
显示剩余5条评论
2个回答

5

如果这只是一次性的事情,你可能会更容易地使用一个字典,但如果你倾向于保持结构,你也可以使用反射来完成。

这个小代码片段将为您在一个StringBuilder中列出每个结构成员。

Dim sbOutput As New System.Text.StringBuilder
Dim t As Type = GetType(xyz)
For Each p As System.Reflection.FieldInfo In t.GetFields()
  sbOutput.AppendLine(p.Name)
Next

你能否在答案中添加反射代码以添加p.Name变量的值来“改进”它?谢谢。 - schlebe

1

虽然这是一个老问题,但我发现自己也需要这个功能,并且这是谷歌为我提供的顶级结果之一,因此我想为将来路过的任何人做出贡献。

在我的情况下,我基本上使用这个结构作为字符串的集合,可以通过StrucName.Value1等轻松引用(基本上是字符串的枚举,就像这里问到的那样),并且不必太担心拼写检查(与字典相比,无论您是否像上面评论中所述使用了dict!foo方法)。我90%的使用情况只需要一两个值,但我在我的代码中找到了一两个地方,它们更好/更容易地循环遍历所有成员值并执行(基本上)相同的操作,而不是将每个值单独列出在自己的行中。

我找到了一个好的答案,它不使用反射在另一个网站上,其中评论者建议要么覆盖ToString函数,要么使用返回值数组的函数。当然,从技术上讲,这仍然需要您再次编写结构的所有成员,但如果反射真的对性能有很大影响,那么这可能更好。
最终我使用了返回值为数组的函数方法,如下所示:
Public Structure StrucName
    Public Const Value1 As String = "Value1"
    Public Const Value2 As String = "Value2"
    Public Const Value3 As String = "Value3"
    'etc
    Public Shared Function GetMemberValues() As String()
        Return {Value1, Value2, Value3} 'etc
    End Function
End Structure

然后你可以像这样在代码中使用它:
Dim values As String() = StrucName.GetMemberValues()
For Each value As String In values
    'do stuff
Next

如果您的结构包含多个值类型,则可以使用 ArrayList
Public Structure StrucName
    Public Const Value1 As String = "Value1"
    Public Const Value2 As Integer = 2
    Public Const Value3 As Boolean = True
    'etc
    Public Shared Function GetMemberValues() As ArrayList
        Return New ArrayList From {Value1, Value2, Value3} 'etc
    End Function
End Structure

Dim values As ArrayList = StrucName.GetMemberValues()
For Each value As Object In values
    'do stuff
Next

使用 ArrayList 方法,如果需要,您可以通过 value.GetType() 或任何其他类似的运算符或方法获取原始值的类型(因此,对于上面的示例,在我们的“执行操作”区域中放置 MsgBox(value.GetType().ToString()) 将弹出消息框,显示“System.String”、“System.Int32”和“System.Boolean”)。
我想这可以适应许多情况。例如,如果您需要成员名称和值,则可以返回一个 Dictionary
Public Shared Function GetMemberValues() As Dictionary(Of String, Object)
    Return New Dictionary(Of String, Object) From {{"Value1", Value1}, {"Value2", Value2}, {"Value3", Value3}} 'etc
End Function

或者,如果您使用的是足够新的VB版本(VB14或更高版本),您可以使用NameOf运算符(MS Doc here):

Public Shared Function GetMemberValues() As Dictionary(Of String, Object)
    Return New Dictionary(Of String, Object) From {{NameOf(Value1), Value1}, {NameOf(Value2), Value2}, {NameOf(Value3), Value3}} 'etc
End Function

Dim values As Dictionary(Of String, Object) = StrucName.GetMemberValues()
For Each kvp As KeyValuePair(Of String, Object) In values
    'do stuff
Next

kvp.value.GetType() 仍然有效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接