PC Review Forums Newsgroups Microsoft DotNet Microsoft Dot NET Framework Forms Setting properties by name

Reply

Setting properties by name

 
Thread Tools Rate Thread
Old 10-02-2006, 01:58 PM   #1
Alexander Walker
Guest
 
Posts: n/a
Default 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(object instance, string property, object value)
{
//TODO: set the named property of the instance with the value
}

The method could be called like this

SetProperty(myClassInstance, "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(myClassInstance, 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


  Reply With Quote
Old 10-02-2006, 02:06 PM   #2
Marc Gravell
Guest
 
Posts: n/a
Default Re: Setting properties by name

Reflection:

instance.GetType().GetProperty(property).SetValue(instance, value, null);

(assumes public, writeable, instance property)

Marc


  Reply With Quote
Old 10-02-2006, 02:23 PM   #3
Stoitcho Goutsev \(100\)
Guest
 
Posts: n/a
Default 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(MyProperty);
pi.SetValue(myClassInstance, myValue, null);

Type.GetProperty 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.noemail> wrote in message
news:%23%239LUokLGHA.3276@TK2MSFTNGP09.phx.gbl...
> 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(object instance, string property, object value)
> {
> //TODO: set the named property of the instance with the value
> }
>
> The method could be called like this
>
> SetProperty(myClassInstance, "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(myClassInstance, 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
>
>



  Reply With Quote
Old 10-02-2006, 02:26 PM   #4
Claes Bergefall
Guest
 
Posts: n/a
Default 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:
' MissingMemberException - No property or get method matching the
specified name or parameters was found
' MissingMethodException - No get method was found (property is
write-only)
Public Shared Function GetProperty(ByVal 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.Instance Or _
BindingFlags.Static Or _
BindingFlags.NonPublic Or _
BindingFlags.Public

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

While Not objectType Is Nothing
propertyInfo = objectType.GetProperty(name, flags, Nothing, Nothing,
types, Nothing)
If propertyInfo Is Nothing Then
objectType = objectType.BaseType
Else
Exit While
End If
End While

If propertyInfo Is Nothing Then
Throw New MissingMemberException(obj.GetType.FullName, "")
ElseIf Not propertyInfo.CanRead Then
Throw New MissingMethodException(obj.GetType.FullName, "")
Else
Return propertyInfo.GetValue(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:
' MissingMemberException - No property matching the specified name or
parameters was found
' MissingMethodException - No set method was found (property is
read-only)
Public Shared Sub SetProperty(ByVal 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.Instance Or _
BindingFlags.Static Or _
BindingFlags.NonPublic Or _
BindingFlags.Public

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

While Not objectType Is Nothing
propertyInfo = objectType.GetProperty(name, flags, Nothing, Nothing,
types, Nothing)
If propertyInfo Is Nothing Then
objectType = objectType.BaseType
Else
Exit While
End If
End While

If propertyInfo Is Nothing Then
Throw New MissingMemberException(obj.GetType.FullName, "")
ElseIf Not propertyInfo.CanWrite Then
Throw New MissingMethodException(obj.GetType.FullName, "")
Else
propertyInfo.SetValue(obj, value, params)
End If
End Sub


/claes

"Alexander Walker" <alex@noemail.noemail> wrote in message
news:%23%239LUokLGHA.3276@TK2MSFTNGP09.phx.gbl...
> 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(object instance, string property, object value)
> {
> //TODO: set the named property of the instance with the value
> }
>
> The method could be called like this
>
> SetProperty(myClassInstance, "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(myClassInstance, 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
>
>



  Reply With Quote
Old 10-02-2006, 07:01 PM   #5
Herfried K. Wagner [MVP]
Guest
 
Posts: n/a
Default Re: Setting properties by name

"Claes Bergefall" <claes.bergefall@nospam.nospam> schrieb:
> 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:


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/>

  Reply With Quote
Old 11-02-2006, 12:07 AM   #6
Alexander Walker
Guest
 
Posts: n/a
Default Re: Setting properties by name

Here are the methods I came up with

delegate object GetPropertyCallback(object parent, object control,
string propertyName);
delegate void SetPropertyCallback(object parent, object control, string
propertyName, object value);

public object GetProperty(object parent, object control, string
propertyName)
{
Control instance = null;
if (parent != null)
{
instance = (Control)parent;
}
else
{
instance = (Control)control;
}
if (instance.InvokeRequired)
{
GetPropertyCallback d = new GetPropertyCallback(GetProperty);
return instance.Invoke(d, new object[] { parent, control,
propertyName });
}
else
{
return
control.GetType().GetProperty(propertyName).GetValue(control, null);
}
}

public void SetProperty(object parent, object control, string
propertyName, object value)
{
Control instance = null;
if (parent != null)
{
instance = (Control)parent;
}
else
{
instance = (Control)control;
}
if (instance.InvokeRequired)
{
SetPropertyCallback d = new SetPropertyCallback(SetProperty);
instance.Invoke(d, new object[] { parent, control, propertyName,
value });
}
else
{
control.GetType().GetProperty(propertyName).SetValue(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


  Reply With Quote
Old 11-02-2006, 07:16 PM   #7
Marc Gravell
Guest
 
Posts: n/a
Default 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
GetPropertyDelegate?

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


  Reply With Quote
Old 11-02-2006, 07:45 PM   #8
Marc Gravell
Guest
 
Posts: n/a
Default 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(object obj, string propertyName) {
return GetProperty(obj as Control, obj, propertyName);
}

public static object GetProperty(Control parent, object obj, string
propertyName) {
if(parent==null || !parent.InvokeRequired) {
// 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
ISynchronizeInvoke, but that is probably overkill.

Marc


  Reply With Quote
Old 13-02-2006, 02:36 PM   #9
Claes Bergefall
Guest
 
Posts: n/a
Default 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:uqSkSRnLGHA.1180@TK2MSFTNGP09.phx.gbl...
> "Claes Bergefall" <claes.bergefall@nospam.nospam> schrieb:
>> 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:

>
> 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/>



  Reply With Quote
Reply



Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off