471,316 Members | 989 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,316 software developers and data experts.

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
Feb 10 '06 #1
11 3318
Reflection:

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

(assumes public, writeable, instance property)

Marc
Feb 10 '06 #2
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" <al**@noemail.noemail> wrote in message
news:%2******************@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

Feb 10 '06 #3
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" <al**@noemail.noemail> wrote in message
news:%2******************@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

Feb 10 '06 #4
"Claes Bergefall" <cl*************@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/>

Feb 10 '06 #5
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).GetVal ue(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).SetVal ue(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
Feb 11 '06 #6
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
Feb 11 '06 #7
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
Feb 11 '06 #8
Hmm, guess I could. Didn't know about that one :-)
Does it work with private members as well?

/claes
"Herfried K. Wagner [MVP]" <hi***************@gmx.at> wrote in message
news:uq**************@TK2MSFTNGP09.phx.gbl...
"Claes Bergefall" <cl*************@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/>

Feb 13 '06 #9
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.)

--------------------
From: "Alexander Walker" <al**@noemail.noemail>
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: <##**************@TK2MSFTNGP09.phx.gbl>
Newsgroups: microsoft.public.dotnet.framework.windowsforms,mic rosoft.public.dotnet.langu
ages.csharpNNTP-Posting-Host: 213-208-113-136.dyn.gotadsl.co.uk 213.208.113.136
Path: TK2MSFTNGXA01.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFT NGP09.phx.gbl
Xref: TK2MSFTNGXA01.phx.gbl microsoft.public.dotnet.languages.csharp:385054
microsoft.public.dotnet.framework.windowsforms:940 79X-Tomcat-NG: microsoft.public.dotnet.languages.csharp

Hello

I would like to write a method that allows me to pass a reference to an instanceof 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 instancein a late bound manner, or is it even possible to pass a reference to the actualproperty like so

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

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

Alex


Feb 15 '06 #10
Hello Terry,

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

Thank you

Alex
Feb 17 '06 #11
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

--------------------
From: "Alexander Walker" <al**@noemail.noemail>
References: <##**************@TK2MSFTNGP09.phx.gbl> <Tc*************@TK2MSFTNGXA01.phx.gbl>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: <uN**************@TK2MSFTNGP09.phx.gbl>
Newsgroups: microsoft.public.dotnet.languages.csharp
NNTP-Posting-Host: 84.12.81.6
Path: TK2MSFTNGXA01.phx.gbl!TK2MSFTNGP08.phx.gbl!TK2MSFT NGP09.phx.gbl
Xref: TK2MSFTNGXA01.phx.gbl microsoft.public.dotnet.languages.csharp:386630
X-Tomcat-NG: microsoft.public.dotnet.languages.csharp

Hello Terry,

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

Thank you

Alex


Feb 17 '06 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Danko Greiner | last post: by
1 post views Thread by Rob Meade | last post: by
3 posts views Thread by John Dann | last post: by
3 posts views Thread by Ryan Liu | last post: by
reply views Thread by rosydwin | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.