VB.NET:通过反射实例化一个嵌套的属性
VB.NET: Instantiate a nested property by reflection
我想通过反射设置属性的值。在这个 thread 他们提出了一个解决方案。但解决方案的问题在于它没有实例化属性。但我想在必要时检查并实例化属性。我的 DTO 是:
Public Class root
Public Property Printing() As rootPrinting
End Class
Public Class rootPrinting
Public Property Printer() As String
Public Property PrinterBatch() As String
End Class
现在为了设置属性,我定义了以下函数:
Public Sub SetProperty(ByVal target As Object, ByVal compoundProperty As String, ByVal value As Object)
Dim properties As String() = compoundProperty.Split("."c)
For i As Integer = 0 To properties.Length - 1 - 1
Dim propertyToGet As PropertyInfo = target.[GetType]().GetProperty(properties(i))
target = propertyToGet.GetValue(target, Nothing)
if IsNothing(target) then
if propertyToGet.PropertyType.IsClass then
target = Activator.CreateInstance(propertyToGet.PropertyType)
End If
End If
Next
Dim propertyToSet As PropertyInfo = target.[GetType]().GetProperty(properties.Last())
propertyToSet.SetValue(target, value, Nothing)
End Sub
然后我这样称呼它:
Dim configObject as New root
SetProperty(configObject , "Printing.Printer","skjfkd")
如果在调用 SetProperty(configObject,...)
之前我实例化 configObject.Printing
那么它将正常工作:
Dim configObject as New root
configObject.Printing = new rootPrinting()
SetProperty(configObject , "Printing.Printer","skjfkd")
否则在调用SetProperty(...)
后,configObject.Printing
将是Nothing
。
似乎在调用 Activator.CreateInstance(propertyToGet.PropertyType)
时,对原始对象的引用丢失了。虽然函数中的对象真正初始化了,但主要对象仍然是Nothing
。如何正确实例化 class 属性?
好的。问题解决了。要解决此问题,必须按以下方式修改代码:
Public Sub SetProperty(ByVal target As Object, ByVal compoundProperty As String, ByVal value As Object)
Dim properties As String() = compoundProperty.Split("."c)
For i As Integer = 0 To properties.Length - 1 - 1
Dim propertyToGet As PropertyInfo = target.GetType().GetProperty(properties(i))
Dim property_value = propertyToGet.GetValue(target, Nothing)
If IsNothing(property_value) Then
If propertyToGet.PropertyType.IsClass Then
property_value = Activator.CreateInstance(propertyToGet.PropertyType)
propertyToGet.SetValue(target, property_value)
End If
End If
target = property_value
Next
Dim propertyToSet As PropertyInfo = target.GetType().GetProperty(properties.Last())
propertyToSet.SetValue(target, value)
End Sub
这个 question/answer 对我很有帮助(感谢 Code Pope!),我在 C# 中需要相同的代码:
public void SetProperty(object target, string compoundProperty, object value)
{
var properties = compoundProperty.Split('.');
for (int i=0; i < (properties.Length - 1); i++)
{
var propertyToGet = target.GetType().GetProperty(properties[i]);
var property_value = propertyToGet.GetValue(target, null);
if (property_value == null)
{
if (propertyToGet.PropertyType.IsClass)
{
property_value = Activator.CreateInstance(propertyToGet.PropertyType);
propertyToGet.SetValue(target, property_value);
}
}
target = property_value;
}
var propertyToSet = target.GetType().GetProperty(properties.Last());
propertyToSet.SetValue(target, value);
}
我想通过反射设置属性的值。在这个 thread 他们提出了一个解决方案。但解决方案的问题在于它没有实例化属性。但我想在必要时检查并实例化属性。我的 DTO 是:
Public Class root
Public Property Printing() As rootPrinting
End Class
Public Class rootPrinting
Public Property Printer() As String
Public Property PrinterBatch() As String
End Class
现在为了设置属性,我定义了以下函数:
Public Sub SetProperty(ByVal target As Object, ByVal compoundProperty As String, ByVal value As Object)
Dim properties As String() = compoundProperty.Split("."c)
For i As Integer = 0 To properties.Length - 1 - 1
Dim propertyToGet As PropertyInfo = target.[GetType]().GetProperty(properties(i))
target = propertyToGet.GetValue(target, Nothing)
if IsNothing(target) then
if propertyToGet.PropertyType.IsClass then
target = Activator.CreateInstance(propertyToGet.PropertyType)
End If
End If
Next
Dim propertyToSet As PropertyInfo = target.[GetType]().GetProperty(properties.Last())
propertyToSet.SetValue(target, value, Nothing)
End Sub
然后我这样称呼它:
Dim configObject as New root
SetProperty(configObject , "Printing.Printer","skjfkd")
如果在调用 SetProperty(configObject,...)
之前我实例化 configObject.Printing
那么它将正常工作:
Dim configObject as New root
configObject.Printing = new rootPrinting()
SetProperty(configObject , "Printing.Printer","skjfkd")
否则在调用SetProperty(...)
后,configObject.Printing
将是Nothing
。
似乎在调用 Activator.CreateInstance(propertyToGet.PropertyType)
时,对原始对象的引用丢失了。虽然函数中的对象真正初始化了,但主要对象仍然是Nothing
。如何正确实例化 class 属性?
好的。问题解决了。要解决此问题,必须按以下方式修改代码:
Public Sub SetProperty(ByVal target As Object, ByVal compoundProperty As String, ByVal value As Object)
Dim properties As String() = compoundProperty.Split("."c)
For i As Integer = 0 To properties.Length - 1 - 1
Dim propertyToGet As PropertyInfo = target.GetType().GetProperty(properties(i))
Dim property_value = propertyToGet.GetValue(target, Nothing)
If IsNothing(property_value) Then
If propertyToGet.PropertyType.IsClass Then
property_value = Activator.CreateInstance(propertyToGet.PropertyType)
propertyToGet.SetValue(target, property_value)
End If
End If
target = property_value
Next
Dim propertyToSet As PropertyInfo = target.GetType().GetProperty(properties.Last())
propertyToSet.SetValue(target, value)
End Sub
这个 question/answer 对我很有帮助(感谢 Code Pope!),我在 C# 中需要相同的代码:
public void SetProperty(object target, string compoundProperty, object value)
{
var properties = compoundProperty.Split('.');
for (int i=0; i < (properties.Length - 1); i++)
{
var propertyToGet = target.GetType().GetProperty(properties[i]);
var property_value = propertyToGet.GetValue(target, null);
if (property_value == null)
{
if (propertyToGet.PropertyType.IsClass)
{
property_value = Activator.CreateInstance(propertyToGet.PropertyType);
propertyToGet.SetValue(target, property_value);
}
}
target = property_value;
}
var propertyToSet = target.GetType().GetProperty(properties.Last());
propertyToSet.SetValue(target, value);
}