Setting properties by name

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Alexander Walker

    Setting properties by name

    Hello

    I would like to write a method that allows me to pass a reference to an instance
    of a class, the name of a property of that class and a value to set that
    property to, the method would then set the property of the instance to the value

    here is an example of what the method might look like

    public void SetProperty(obj ect instance, string property, object value)
    {
    //TODO: set the named property of the instance with the value
    }

    The method could be called like this

    SetProperty(myC lassInstance, "MyProperty ", "My Value");

    How would such a method be written? how do you access the members of an instance
    in a late bound manner, or is it even possible to pass a reference to the actual
    property like so

    SetProperty(myC lassInstance, myClassInstance .MyProperty, "The Value");

    Where the method is not taking the value of myClassInstance .MyProperty but the
    reference to the actual property so that it can set its value, is this possible?

    Thanks

    Alex


  • Marc Gravell

    #2
    Re: Setting properties by name

    Reflection:

    instance.GetTyp e().GetProperty (property).SetV alue(instance, value, null);

    (assumes public, writeable, instance property)

    Marc


    Comment

    • Stoitcho Goutsev \(100\)

      #3
      Re: Setting properties by name

      Alexander,

      Look at the .net reflection.

      The code for setting the property would look something like this:

      Type t = myClassInstance .GetType();
      PropertyInfo pi = t.GetProperty(M yProperty);
      pi.SetValue(myC lassInstance, myValue, null);

      Type.GetPropert y method has more than one overload. You may need to use some
      of the others depending on the visibility of the property.

      If you want to pass "instance of a property" you can use the PropertyInfo
      class.



      --
      HTH
      Stoitcho Goutsev (100)

      "Alexander Walker" <alex@noemail.n oemail> wrote in message
      news:%23%239LUo kLGHA.3276@TK2M SFTNGP09.phx.gb l...[color=blue]
      > Hello
      >
      > I would like to write a method that allows me to pass a reference to an
      > instance
      > of a class, the name of a property of that class and a value to set that
      > property to, the method would then set the property of the instance to the
      > value
      >
      > here is an example of what the method might look like
      >
      > public void SetProperty(obj ect instance, string property, object value)
      > {
      > //TODO: set the named property of the instance with the value
      > }
      >
      > The method could be called like this
      >
      > SetProperty(myC lassInstance, "MyProperty ", "My Value");
      >
      > How would such a method be written? how do you access the members of an
      > instance
      > in a late bound manner, or is it even possible to pass a reference to the
      > actual
      > property like so
      >
      > SetProperty(myC lassInstance, myClassInstance .MyProperty, "The Value");
      >
      > Where the method is not taking the value of myClassInstance .MyProperty but
      > the
      > reference to the actual property so that it can set its value, is this
      > possible?
      >
      > Thanks
      >
      > Alex
      >
      >[/color]


      Comment

      • Claes Bergefall

        #4
        Re: Setting properties by name

        Here are some methods I've been using to accomplish that (both Set and Get).
        They're in VB.NET though so you'll have to translate them:

        ' Description:
        ' Calls the get method for a property on an object using reflection.
        GetProperty
        ' searches the inheritance chain until it finds a match. All access
        levels
        ' (private, public etc) are supported
        ' Parameters:
        ' name - Name of property to get
        ' object - Object on which to get the property value
        ' params - Optional parameters to the property
        ' Return value:
        ' The returned value of the property's get method
        ' Exceptions:
        ' MissingMemberEx ception - No property or get method matching the
        specified name or parameters was found
        ' MissingMethodEx ception - No get method was found (property is
        write-only)
        Public Shared Function GetProperty(ByV al name As String, ByVal obj As
        Object, ByVal ParamArray params() As Object) As Object
        Dim objectType As Type = obj.GetType
        Dim flags As BindingFlags = BindingFlags.In stance Or _
        BindingFlags.St atic Or _
        BindingFlags.No nPublic Or _
        BindingFlags.Pu blic

        Dim propertyInfo As PropertyInfo
        Dim types(params.Le ngth - 1) As Type
        Dim index As Integer
        For index = 0 To params.Length - 1
        types(index) = params(index).G etType
        Next

        While Not objectType Is Nothing
        propertyInfo = objectType.GetP roperty(name, flags, Nothing, Nothing,
        types, Nothing)
        If propertyInfo Is Nothing Then
        objectType = objectType.Base Type
        Else
        Exit While
        End If
        End While

        If propertyInfo Is Nothing Then
        Throw New MissingMemberEx ception(obj.Get Type.FullName, "")
        ElseIf Not propertyInfo.Ca nRead Then
        Throw New MissingMethodEx ception(obj.Get Type.FullName, "")
        Else
        Return propertyInfo.Ge tValue(obj, params)
        End If
        End Function

        ' Description:
        ' Calls the set method for a property on an object using reflection.
        SetProperty
        ' searches the inheritance chain until it finds a match. All access
        levels
        ' (private, public etc) are supported
        ' Parameters:
        ' name - Name of property to set
        ' object - Object on which to set the property value
        ' value - Value to assign to the property
        ' params - Optional parameters to the property
        ' Return value:
        ' None
        ' Exceptions:
        ' MissingMemberEx ception - No property matching the specified name or
        parameters was found
        ' MissingMethodEx ception - No set method was found (property is
        read-only)
        Public Shared Sub SetProperty(ByV al name As String, ByVal obj As Object,
        ByVal value As Object, ByVal ParamArray params() As Object)
        Dim objectType As Type = obj.GetType
        Dim flags As BindingFlags = BindingFlags.In stance Or _
        BindingFlags.St atic Or _
        BindingFlags.No nPublic Or _
        BindingFlags.Pu blic

        Dim propertyInfo As PropertyInfo
        Dim types(params.Le ngth - 1) As Type
        Dim index As Integer
        For index = 0 To params.Length - 1
        types(index) = params(index).G etType
        Next

        While Not objectType Is Nothing
        propertyInfo = objectType.GetP roperty(name, flags, Nothing, Nothing,
        types, Nothing)
        If propertyInfo Is Nothing Then
        objectType = objectType.Base Type
        Else
        Exit While
        End If
        End While

        If propertyInfo Is Nothing Then
        Throw New MissingMemberEx ception(obj.Get Type.FullName, "")
        ElseIf Not propertyInfo.Ca nWrite Then
        Throw New MissingMethodEx ception(obj.Get Type.FullName, "")
        Else
        propertyInfo.Se tValue(obj, value, params)
        End If
        End Sub


        /claes

        "Alexander Walker" <alex@noemail.n oemail> wrote in message
        news:%23%239LUo kLGHA.3276@TK2M SFTNGP09.phx.gb l...[color=blue]
        > Hello
        >
        > I would like to write a method that allows me to pass a reference to an
        > instance
        > of a class, the name of a property of that class and a value to set that
        > property to, the method would then set the property of the instance to the
        > value
        >
        > here is an example of what the method might look like
        >
        > public void SetProperty(obj ect instance, string property, object value)
        > {
        > //TODO: set the named property of the instance with the value
        > }
        >
        > The method could be called like this
        >
        > SetProperty(myC lassInstance, "MyProperty ", "My Value");
        >
        > How would such a method be written? how do you access the members of an
        > instance
        > in a late bound manner, or is it even possible to pass a reference to the
        > actual
        > property like so
        >
        > SetProperty(myC lassInstance, myClassInstance .MyProperty, "The Value");
        >
        > Where the method is not taking the value of myClassInstance .MyProperty but
        > the
        > reference to the actual property so that it can set its value, is this
        > possible?
        >
        > Thanks
        >
        > Alex
        >
        >[/color]


        Comment

        • Herfried K. Wagner [MVP]

          #5
          Re: Setting properties by name

          "Claes Bergefall" <claes.bergefal l@nospam.nospam > schrieb:[color=blue]
          > Here are some methods I've been using to accomplish that (both Set and
          > Get). They're in VB.NET though so you'll have to translate them:[/color]

          Mhm... You could use 'CallByName' in VB.NET instead of these methods ;-).

          --
          M S Herfried K. Wagner
          M V P <URL:http://dotnet.mvps.org/>
          V B <URL:http://classicvb.org/petition/>

          Comment

          • Alexander Walker

            #6
            Re: Setting properties by name

            Here are the methods I came up with

            delegate object GetPropertyCall back(object parent, object control,
            string propertyName);
            delegate void SetPropertyCall back(object parent, object control, string
            propertyName, object value);

            public object GetProperty(obj ect parent, object control, string
            propertyName)
            {
            Control instance = null;
            if (parent != null)
            {
            instance = (Control)parent ;
            }
            else
            {
            instance = (Control)contro l;
            }
            if (instance.Invok eRequired)
            {
            GetPropertyCall back d = new GetPropertyCall back(GetPropert y);
            return instance.Invoke (d, new object[] { parent, control,
            propertyName });
            }
            else
            {
            return
            control.GetType ().GetProperty( propertyName).G etValue(control , null);
            }
            }

            public void SetProperty(obj ect parent, object control, string
            propertyName, object value)
            {
            Control instance = null;
            if (parent != null)
            {
            instance = (Control)parent ;
            }
            else
            {
            instance = (Control)contro l;
            }
            if (instance.Invok eRequired)
            {
            SetPropertyCall back d = new SetPropertyCall back(SetPropert y);
            instance.Invoke (d, new object[] { parent, control, propertyName,
            value });
            }
            else
            {
            control.GetType ().GetProperty( propertyName).S etValue(control ,
            value, null);
            }
            }

            I needed a generic way of accessing control properties in a thread safe manner,
            the reason for the parent and the control properties are for those cases where
            the "control" that you are trying to access does not inherit from control and
            does not have an InvokeRequired property, the particular situation I face
            involved a progress bar on a status strip control, the progress bar didn't
            inherit from control and so didn't have an InvokeRequired property, so I passed
            the status strip as the parent

            Thanks

            Alex


            Comment

            • Marc Gravell

              #7
              Re: Setting properties by name

              Some observations:

              Since you always expect parent and control to be Controls, why not specify
              them as Control on the interface?

              The "callback" isn't really what I would call a callback - normally this
              involves an AsyncResult or somesuch; perhaps just call it
              GetPropertyDele gate?

              I can't recall (and don't have an IDE handy), but some of the Invoke methods
              accept a params parameter which makes the call easier; and looks like they
              should be static methods?

              Other than that, it looks like it should work,

              Marc


              Comment

              • Marc Gravell

                #8
                Re: Setting properties by name

                ammendment; I see what you mean about the child; if it must be that way, I'd
                have 2 versions of each

                public static object GetProperty(obj ect obj, string propertyName) {
                return GetProperty(obj as Control, obj, propertyName);
                }

                public static object GetProperty(Con trol parent, object obj, string
                propertyName) {
                if(parent==null || !parent.InvokeR equired) {
                // call directly
                }
                else {
                // invoke (private) delegate
                }
                }

                ===

                Done this way, I can pass any object to the first version of GetProperty; if
                it is a control it will be automatically passed to the right thread; if I
                know I have an object that needs to be accessed on a particular thread I can
                use the second version. You could consider replacing Control with
                ISynchronizeInv oke, but that is probably overkill.

                Marc


                Comment

                • Claes Bergefall

                  #9
                  Re: Setting properties by name

                  Hmm, guess I could. Didn't know about that one :-)
                  Does it work with private members as well?

                  /claes


                  "Herfried K. Wagner [MVP]" <hirf-spam-me-here@gmx.at> wrote in message
                  news:uqSkSRnLGH A.1180@TK2MSFTN GP09.phx.gbl...[color=blue]
                  > "Claes Bergefall" <claes.bergefal l@nospam.nospam > schrieb:[color=green]
                  >> Here are some methods I've been using to accomplish that (both Set and
                  >> Get). They're in VB.NET though so you'll have to translate them:[/color]
                  >
                  > Mhm... You could use 'CallByName' in VB.NET instead of these methods ;-).
                  >
                  > --
                  > M S Herfried K. Wagner
                  > M V P <URL:http://dotnet.mvps.org/>
                  > V B <URL:http://classicvb.org/petition/>[/color]


                  Comment

                  • TerryFei

                    #10
                    RE: Setting properties by name

                    Hi Alexander,

                    I just want to check how things are going and whether or not your problem
                    has been resolved. If there is any question, please feel free to join the
                    community and we are here to support you at your convenience. Thanks again!

                    Best Regards,

                    Terry Fei[MSFT]
                    Microsoft Community Support
                    Get Secure! www.microsoft.com/security
                    (This posting is provided "AS IS", with no warranties, and confers no
                    rights.)

                    --------------------[color=blue]
                    >From: "Alexander Walker" <alex@noemail.n oemail>
                    >Subject: Setting properties by name
                    >Date: Fri, 10 Feb 2006 13:58:27 -0000
                    >Lines: 31
                    >X-Priority: 3
                    >X-MSMail-Priority: Normal
                    >X-Newsreader: Microsoft Outlook Express 6.00.2900.2670
                    >X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2670
                    >Message-ID: <##9LUokLGHA.32 76@TK2MSFTNGP09 .phx.gbl>
                    >Newsgroups:[/color]
                    microsoft.publi c.dotnet.framew ork.windowsform s,microsoft.pub lic.dotnet.lang u
                    ages.csharp[color=blue]
                    >NNTP-Posting-Host: 213-208-113-136.dyn.gotadsl .co.uk 213.208.113.136
                    >Path: TK2MSFTNGXA01.p hx.gbl!TK2MSFTN GP08.phx.gbl!TK 2MSFTNGP09.phx. gbl
                    >Xref: TK2MSFTNGXA01.p hx.gbl[/color]
                    microsoft.publi c.dotnet.langua ges.csharp:3850 54
                    microsoft.publi c.dotnet.framew ork.windowsform s:94079[color=blue]
                    >X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.csharp
                    >
                    >Hello
                    >
                    >I would like to write a method that allows me to pass a reference to an[/color]
                    instance[color=blue]
                    >of a class, the name of a property of that class and a value to set that
                    >property to, the method would then set the property of the instance to the[/color]
                    value[color=blue]
                    >
                    >here is an example of what the method might look like
                    >
                    >public void SetProperty(obj ect instance, string property, object value)
                    >{
                    >//TODO: set the named property of the instance with the value
                    >}
                    >
                    >The method could be called like this
                    >
                    >SetProperty(my ClassInstance, "MyProperty ", "My Value");
                    >
                    >How would such a method be written? how do you access the members of an[/color]
                    instance[color=blue]
                    >in a late bound manner, or is it even possible to pass a reference to the[/color]
                    actual[color=blue]
                    >property like so
                    >
                    >SetProperty(my ClassInstance, myClassInstance .MyProperty, "The Value");
                    >
                    >Where the method is not taking the value of myClassInstance .MyProperty but[/color]
                    the[color=blue]
                    >reference to the actual property so that it can set its value, is this[/color]
                    possible?[color=blue]
                    >
                    >Thanks
                    >
                    >Alex
                    >
                    >
                    >[/color]

                    Comment

                    • Alexander Walker

                      #11
                      Re: Setting properties by name

                      Hello Terry,

                      I have been able to use the two methods that I posted earlier to satisfy my
                      needs

                      Thank you

                      Alex


                      Comment

                      • TerryFei

                        #12
                        Re: Setting properties by name

                        Hi Alex,
                        Thanks for your update! :)

                        I am glad to know that the problem has been resolved now. Thanks for
                        participating the community!

                        Best Regards,

                        Terry Fei [MSFT]
                        Microsoft Community Support
                        Get Secure! www.microsoft.com/security

                        --------------------[color=blue]
                        >From: "Alexander Walker" <alex@noemail.n oemail>
                        >References: <##9LUokLGHA.32 76@TK2MSFTNGP09 .phx.gbl>[/color]
                        <TcfAHDhMGHA.12 8@TK2MSFTNGXA01 .phx.gbl>[color=blue]
                        >Subject: Re: Setting properties by name
                        >Date: Fri, 17 Feb 2006 03:44:31 -0000
                        >Lines: 10
                        >X-Priority: 3
                        >X-MSMail-Priority: Normal
                        >X-Newsreader: Microsoft Outlook Express 6.00.2900.2670
                        >X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2670
                        >Message-ID: <uNC04R3MGHA.12 88@TK2MSFTNGP09 .phx.gbl>
                        >Newsgroups: microsoft.publi c.dotnet.langua ges.csharp
                        >NNTP-Posting-Host: 84.12.81.6
                        >Path: TK2MSFTNGXA01.p hx.gbl!TK2MSFTN GP08.phx.gbl!TK 2MSFTNGP09.phx. gbl
                        >Xref: TK2MSFTNGXA01.p hx.gbl microsoft.publi c.dotnet.langua ges.csharp:3866 30
                        >X-Tomcat-NG: microsoft.publi c.dotnet.langua ges.csharp
                        >
                        >Hello Terry,
                        >
                        >I have been able to use the two methods that I posted earlier to satisfy[/color]
                        my[color=blue]
                        >needs
                        >
                        >Thank you
                        >
                        >Alex
                        >
                        >
                        >[/color]

                        Comment

                        Working...