PC Review
Forums
Newsgroups
Microsoft DotNet
Microsoft Dot NET Framework Forms
Setting properties by name
Forums
Newsgroups
Microsoft DotNet
Microsoft Dot NET Framework Forms
Setting properties by name
![]() |
Setting properties by name |
|
|
Thread Tools | Rate Thread |
|
|
#1 |
|
Guest
Posts: n/a
|
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 |
|
|
|
#2 |
|
Guest
Posts: n/a
|
Reflection:
instance.GetType().GetProperty(property).SetValue(instance, value, null); (assumes public, writeable, instance property) Marc |
|
|
|
#3 |
|
Guest
Posts: n/a
|
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 > > |
|
|
|
#4 |
|
Guest
Posts: n/a
|
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 > > |
|
|
|
#5 |
|
Guest
Posts: n/a
|
"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/> |
|
|
|
#6 |
|
Guest
Posts: n/a
|
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 |
|
|
|
#7 |
|
Guest
Posts: n/a
|
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 |
|
|
|
#8 |
|
Guest
Posts: n/a
|
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 |
|
|
|
#9 |
|
Guest
Posts: n/a
|
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/> |
|
![]() |
|
| Thread Tools | |
| Rate This Thread | |
|
|

Main Page 

