VB.NET: Instantiate a nested property by reflection

别说谁变了你拦得住时间么 提交于 2019-12-11 08:06:23

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!