问题
I want to set the values of the properties via reflection. In this thread they propose a solution. But the problem with the solution is that it is not instantiating the properties. But I want to check and instantiate the properties if necessary. My DTO is:
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
Now for setting the properties I have defined the following function:
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
Then I call it like this:
Dim configObject as New root
SetProperty(configObject , "Printing.Printer","skjfkd")
If before calling SetProperty(configObject,...)
I instantiate configObject.Printing
then it will work fine:
Dim configObject as New root
configObject.Printing = new rootPrinting()
SetProperty(configObject , "Printing.Printer","skjfkd")
Otherwise after calling SetProperty(...)
, configObject.Printing
will be Nothing
.
It seems that when calling Activator.CreateInstance(propertyToGet.PropertyType)
the reference to the original object is lost. While the object in the function is really initialized, the main object remains Nothing
. How can I instantiate the class property correctly?
回答1:
This question/answer was very helpful to me (thanks Code Pope!), I needed the same code in 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);
}
回答2:
Ok. The problem was solved. To solve the problem the code has to be modified as following:
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
来源:https://stackoverflow.com/questions/51934180/vb-net-instantiate-a-nested-property-by-reflection