我有一个包含一些列表属性的类:
Public Class ListPropertiesClass
Public Property Id As List(Of Int32)
End Class
另一个我使用Reflection的课程:
Public Class Test
Public Sub MySub()
Dim IdentityValue as Int32 = 100
Dim PropertyName as String = "Id"
Dim LPC as new ListPropertiesClass
Dim pInfo As PropertyInfo
pInfo = LPC.GetType().GetProperty(PropertyName)
If Not pInfo Is Nothing Then
pInfo.SetValue(LPC, Convert.ToInt32(IdentityValue), Nothing)
End If
End Sub
End Class
但是当我尝试使用它时它不起作用,因为我试图将类型Int32的值设置为List 1,我如何使用PropertyInfo.SetValue添加列表Itens?添加后,如何使用反射获取值以获取列表特定索引的值
pInfo.GetValue(LPC, Nothing)
如果有人能帮助我,我会很高兴。感谢。
答案 0 :(得分:0)
你必须先得到当前属性的值(并检查它),如下所示
这是例如,因为我不记得vb.net的确切语法
Dim pValue = pInfo.GetValue(LPC, Nothing)
Dim castedValue As List(Of Integer) = TryCast(pValue, List(Of Integer))
If castedValue Is Nothing Then
castedValue = New List(Of Integer)()
End If
castedValue.Add(IdentityValue)
pInfo.SetValue(LPC, Convert.ToInt32(IdentityValue), Nothing)
答案 1 :(得分:0)
首先,正如您已经指出的那样,您无法为Int32
属性分配List(Of Int32)
值。
其次,我不确定你要完全尝试完成什么,但我会同意它 - 让我们分配一个的新实例使用
List(Of Int32)
实例对该媒体资源的引用
这里什么都没有:
Dim newList As New List(Of Int32)
pInfo.SetValue(LPC, newList, Nothing)
现在,您可以在列表中添加内容(您已经有了对它的引用):
Dim newList As New List(Of Int32)
pInfo.SetValue(LPC, newList, Nothing)
newList.Add(10)
newList.Add(11);
它不是存储列表的属性。 该属性存储引用(4字节= 32位长的数值)。 引用,指针或地址不是实际的实例。
您可以使用引用对实例执行操作,并且可以对同一实例进行多次引用。
观点变更
假设你对我刚刚做的反射玩兴趣不感兴趣。假设您同意以下修改:
Public Class ListPropertiesClass
Public Property Id As List(Of Int32)
Sub New()
Property = New List(Of Int32)
End Sub
End Class
基本上,List(Of Int32)
的每个实例都需要一个ListPropertiesClass
的实例,这是一个微不足道的事情,所以让我们简单地创建List(Of Int32)
及其中的Int32
#39; s包装 - 这里没有反思。
现在,假设您要使用Reflection将LPC.Property.Add(10) ' LINE 1
值添加到该列表中。
首先看看如何在没有反思的情况下实现这一目标:
Dim theList As List(Of Int32) ' LINE 2
theList = LPC.Property ' LINE 3
theList.Add(10) ' LINE 4
可以翻译成这个等效的代码:
' LINE 1
如果您不完全确定最后3行与' LINE 2
注释的行具有完全相同的效果,那么我建议您刷新一般OOP中的类,实例和引用。< / p>
现在,让我们看看最后3行实际上在做什么(不使用Reflection - ):
' LINE 3
只是一个变量声明' LINE 4
是获取操作,后跟作业' LINE 3
是方法的调用因此,这里的关键方面是List(Of Int32)
是获取而不是设置。
现在你要做的是:
我们不会声明一个可以存储Object
引用的变量,而是声明一个可以存储' so this line
' Dim theList as List(Of Int32)
' becomes this line
Dim theList As Object
引用的变量
' so this line
' theList = LPC.Property
' becomes this line
theList = LPC.GetType().GetProperty(PropertyName).GetValue(LPC, Nothing)
而不是&#34;定期进入&#34;并将属性的值赋给变量我们仍然进行赋值,但我们使用反射
获取值GetValue
(请注意跟踪List(Of Int32)
电话)
我们不是简单地使用指向List(Of Int32)
实例的Add
引用向列表添加值,而是使用Object
引用来调用List(Of Int32)
方法。指出 - 你猜对了 - ' so this line
' theList.Add(10)
' becomes this line
theList.GetType().GetMethod("Add").Invoke(theList, New Object() { 10 })
实例
Dim theList As Object
theList = LPC.GetType().GetProperty(PropertyName).GetValue(LPC, Nothing)
theList.GetType().GetMethod("Add").Invoke(theList, New Object() { 10 })
注意Invoke
方法。单击有关它的msdn文章的链接。
总结一下,看起来应该是这样的:
Object
现在,您可以轻松地将List(Of Int32)
引用转换为Add
引用并调用List(Of Int32)
方法而不用反射。在这种情况下,局部变量可以是Dim theList As List(Of Int32)
theList = TryCast(LPC.GetType().GetProperty(PropertyName).GetValue(LPC, Nothing), List(Of Integer))
theList.Add(10)
:
{{1}}祝你好运!