VB.NET: Instantiate a nested property by reflection












1















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?










share|improve this question























  • The DTO classes have public constructors and properties in your example. I assume in the actual project these are all private?

    – Parrish Husband
    Aug 20 '18 at 22:51













  • @ParrishHusband No, in the actual project the the properties are public, too. There just I have private members which are bound to the properties. But to shorten the text I have changed it for this sample.

    – Code Pope
    Aug 21 '18 at 6:01
















1















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?










share|improve this question























  • The DTO classes have public constructors and properties in your example. I assume in the actual project these are all private?

    – Parrish Husband
    Aug 20 '18 at 22:51













  • @ParrishHusband No, in the actual project the the properties are public, too. There just I have private members which are bound to the properties. But to shorten the text I have changed it for this sample.

    – Code Pope
    Aug 21 '18 at 6:01














1












1








1


0






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?










share|improve this question














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?







vb.net reflection propertyinfo






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Aug 20 '18 at 15:38









Code PopeCode Pope

1,30621635




1,30621635













  • The DTO classes have public constructors and properties in your example. I assume in the actual project these are all private?

    – Parrish Husband
    Aug 20 '18 at 22:51













  • @ParrishHusband No, in the actual project the the properties are public, too. There just I have private members which are bound to the properties. But to shorten the text I have changed it for this sample.

    – Code Pope
    Aug 21 '18 at 6:01



















  • The DTO classes have public constructors and properties in your example. I assume in the actual project these are all private?

    – Parrish Husband
    Aug 20 '18 at 22:51













  • @ParrishHusband No, in the actual project the the properties are public, too. There just I have private members which are bound to the properties. But to shorten the text I have changed it for this sample.

    – Code Pope
    Aug 21 '18 at 6:01

















The DTO classes have public constructors and properties in your example. I assume in the actual project these are all private?

– Parrish Husband
Aug 20 '18 at 22:51







The DTO classes have public constructors and properties in your example. I assume in the actual project these are all private?

– Parrish Husband
Aug 20 '18 at 22:51















@ParrishHusband No, in the actual project the the properties are public, too. There just I have private members which are bound to the properties. But to shorten the text I have changed it for this sample.

– Code Pope
Aug 21 '18 at 6:01





@ParrishHusband No, in the actual project the the properties are public, too. There just I have private members which are bound to the properties. But to shorten the text I have changed it for this sample.

– Code Pope
Aug 21 '18 at 6:01












2 Answers
2






active

oldest

votes


















1














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





share|improve this answer































    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);
    }





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51934180%2fvb-net-instantiate-a-nested-property-by-reflection%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      1














      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





      share|improve this answer




























        1














        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





        share|improve this answer


























          1












          1








          1







          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





          share|improve this answer













          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






          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 21 '18 at 15:30









          Code PopeCode Pope

          1,30621635




          1,30621635

























              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);
              }





              share|improve this answer




























                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);
                }





                share|improve this answer


























                  1












                  1








                  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);
                  }





                  share|improve this answer













                  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);
                  }






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jan 2 at 12:03









                  David McClellandDavid McClelland

                  1,55321830




                  1,55321830






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f51934180%2fvb-net-instantiate-a-nested-property-by-reflection%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      MongoDB - Not Authorized To Execute Command

                      in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

                      How to fix TextFormField cause rebuild widget in Flutter