VB.NET 2010~Framework 3.5
有没有办法动态指定类的属性名称?
有时我需要一个从Prop1和Prop2创建的列表 其他时候我需要一个从Prop2和Prop4等创建的列表。目标属性不是提前知道的,它们会随着应用程序的运行而不断变化。 。
Option Strict On
Option Explicit On
Public Class Form1
Private Class Things
Public Property Prop1 As String
Public Property Prop2 As String
Public Property Prop3 As String
Public Property Prop4 As String
End Class
Private Class SubThing
Public Property P1 As String
Public Property P2 As String
End Class
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim mainLst As New List(Of Things)
Dim count As Integer
Do Until count = 20
mainLst.Add(New Things With {.Prop1 = count.ToString, _
.Prop2 = (count + 1).ToString, _
.Prop3 = (count + 2).ToString, _
.Prop4 = (count + 3).ToString})
count += 1
Loop
' Need to dynamically pick properties From mainLst into subLst.
' The commented code below wont compile but demonstrates what I'm trying to do
' can this be done without looping?
'Dim propNameA As String = "Prop1" ' Dynamically specify a property name
'Dim propNameB As String = "Prop4"
'Dim subLst = From mainItem In mainLst
' Select New SubThing() With {.P1 = mainItem.propNameA, .P2 = mainItem.propNameB}
' This code below compiles but lacks the dynamics I need?
Dim subLst = From mainItem In mainLst
Select New SubThing() With {.P1 = mainItem.Prop1, .P2 = mainItem.Prop4}
End Sub
答案 0 :(得分:1)
最直接的方法是使用CallByName
(MSDN Link)。我假设您的示例是您正在使用的简化版本,但似乎更好的方法是摆脱您的Prop1
,Prop2
,{{1} }字符串属性,只需使用一个...
,然后您可以将其编入索引,而无需将属性名称与索引值一起使用frankenstein。例如:
List(Of String)
不确定您的确切用例来自您的示例,但希望这可以指出您正确的方向。
答案 1 :(得分:1)
以下是使用反射作为helrich @建议的示例。 (您必须在.vb文件的顶部Imports System.Reflection
)
1)天真的控制台输出示例:
Dim thingType As Type = GetType(Things)
Dim prop1Property As PropertyInfo = thingType.GetProperty("Prop1")
Dim thingInstance As Things = New Things()
thingInstance.Prop1 = "My Dynamically Accessed Value"
Dim prop1Value = prop1Property.GetValue(thingInstance).ToString()
Console.WriteLine(prop1Value)
2)适应你的例子(“可能”有效,尚未测试):
Dim propNameA As String = "Prop1" ' Dynamically specify a property name
Dim propNameB As String = "Prop4"
Dim propAPropInfo As PropertyInfo = GetType(Things).GetProperty(propNameA)
Dim propBPropInfo As PropertyInfo = GetType(Things).GetProperty(propNameB)
Dim subLst = From mainItem In mainLst
Select New SubThing() With {.P1 = propAPropInfo.GetValue(mainItem).ToString(), .P2 = propBPropInfo.GetValue(mainItem).ToString()}
答案 2 :(得分:0)
Option Strict On
Option Explicit On
Imports System.Reflection
Module Module1
Private Class SourceClass
Public Property Prop1 As String
Public Property Prop2 As String
Public Property Prop3 As String
Public Property Prop4 As String
End Class
Private Class SubClass
Public Property P1 As String
Public Property P2 As String
End Class
Sub Main()
Dim mainLst As New List(Of SourceClass)
Dim count As Integer
Do Until count = 20 ' create source list
mainLst.Add(New SourceClass With {.Prop1 = count.ToString, _
.Prop2 = (count + 1).ToString, _
.Prop3 = (count + 2).ToString, _
.Prop4 = (count + 3).ToString})
count += 1
Loop
Dim propAInfo As PropertyInfo = GetType(SourceClass).GetProperty("Prop1") ' Dynamically specify a property name
Dim propBInfo As PropertyInfo = GetType(SourceClass).GetProperty("Prop3")
' create a list of SubClass from SourceClass
Dim subLst = From mainItem In mainLst Select New SubClass() _
With {.P1 = propAInfo.GetValue(mainItem, Nothing).ToString, _
.P2 = propBInfo.GetValue(mainItem, Nothing).ToString}
count = 0
Do Until count = subLst.Count
Debug.WriteLine(subLst(count).P1 & "~" & subLst(count).P2)
count += 1
Loop
End Sub
End Module