Possible to set/reference a property 'dynamically'?

P

Pritcham

Hi all

I've got a number of classes already developed (basic entity classes)
like the following:

Public Class Contact
Private _firstname as String
Private _age as Integer

Public Property FirstName As String
Get
Return Me._firstname
End Get
Set
If (Me._firstname = value) Then
Return
End If
Me._firstname = value
End If
End Set
End Property

Public Enum PropertyList
FirstName,
Age
End Enum

.....

There are a number of classes like this that describe different
entities (Company, User etc etc) - all of which have a public Enum that
lists each available property for the entity.

I need to write a (separate) function that takes type-safe parameters
based on the properties available with these classes - e.g.

MyFunction(Firstname="John")
or
MyFunction(classname, parameter=value)

I imagined that to do this I would need to create a local instance of
the relevent class (i.e. Contact) in the function and (possibly) use
the param that's passed in the function call in a property setter call,
but that's where I fell over really. Firstly because I won't know the
name of the property to set (and didn't want to use a load of Select
Cases) and secondly because it wouldn't enforce type-safety in the
function call doing it this way).

Firstly, is this possible? If so, how could I go about a) limiting the
parameter that's passed to the function to those listed in the class
enum, and secondly, is it possible to enforce the property-type of the
passed parameter (i.e. if I pass a Firstname param, it will only accept
a string, if I pass an Age param, it'll only accept an Int)?

Sorry if these are stupid questions but I'm still trying to learn .Net
and OOP.

Thanks in advance
Martin
 
T

tomb

Pritcham said:
Hi all

I've got a number of classes already developed (basic entity classes)
like the following:

Public Class Contact
Private _firstname as String
Private _age as Integer

Public Property FirstName As String
Get
Return Me._firstname
End Get
Set
Firstly, the set portion of a property includes the value type:
Set(byval value as string)
Anything other than a string will cause an error.
If (Me._firstname = value) Then
Return
End If
Me._firstname = value
End If
End Set
End Property

Public Enum PropertyList
FirstName,
Age
End Enum

....

There are a number of classes like this that describe different
entities (Company, User etc etc) - all of which have a public Enum that
lists each available property for the entity.
The actual properties of the class list all the properties available in
the class. What is the point of the enum?
I need to write a (separate) function that takes type-safe parameters
based on the properties available with these classes - e.g.

MyFunction(Firstname="John")
or
MyFunction(classname, parameter=value)

I imagined that to do this I would need to create a local instance of
the relevent class (i.e. Contact) in the function and (possibly) use
the param that's passed in the function call in a property setter call,
but that's where I fell over really. Firstly because I won't know the
name of the property to set (and didn't want to use a load of Select
Cases) and secondly because it wouldn't enforce type-safety in the
function call doing it this way).

In order to set a property value, you will have to know the property
name. As such, you can just set the property value directly.
This sounds overly convoluted to me.

Tom
 
P

Pritcham

Hi

Thanks for the reply.

To answer your question(s), the enum is there as the properties are all
based on field names within a db table and this/these are used for
other things as well - the enum lists the actual fields which happen to
also be the name of the properties - just trying to see whether I could
use them in another way. I'm basically trying to incorporate some
type-safe SQL querying into the DAL utilising the properties of the
entities in the BLL.

I've done some more 'experimenting' in the meantime and think it might
be a lot easier to have a kind of helper function for this, passing any
entity to the function (params constrained to those implementing the
base entity interface) so I can basically create a temporary entity for
the query, use this to complete the necessary field/property data
(which deals with the type-safety issue), and pass this to the helper
function along with the other required params that define what this
element of the SQL statement is doing, and built it that way. I know
this is probably doing things 'the wrong way' but it should get the job
done for the meantime.

Thanks again for your input - it is appreciated

Martin
 
J

Jay B. Harlow [MVP - Outlook]

Pritcham,
Have you looked at CallByName?

Something like:
Private Sub MyFunction(ByVal theClass As String, ByVal theProperty As
PropertyList, ByVal theValue As Object)
Dim theType As Type = Type.GetType(theClass)
Dim theObject As Object = Activator.CreateInstance(theType)
CallByName(theObject, theProperty.ToString(), CallType.Set,
theValue)
End Sub

MyFunction("Msi.Viewer.Contact", PropertyList.FirstName, 1)

The "quirk" is that the name of the class needs to include the namespace.


--
Hope this helps
Jay B. Harlow [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


| Hi all
|
| I've got a number of classes already developed (basic entity classes)
| like the following:
|
| Public Class Contact
| Private _firstname as String
| Private _age as Integer
|
| Public Property FirstName As String
| Get
| Return Me._firstname
| End Get
| Set
| If (Me._firstname = value) Then
| Return
| End If
| Me._firstname = value
| End If
| End Set
| End Property
|
| Public Enum PropertyList
| FirstName,
| Age
| End Enum
|
| ....
|
| There are a number of classes like this that describe different
| entities (Company, User etc etc) - all of which have a public Enum that
| lists each available property for the entity.
|
| I need to write a (separate) function that takes type-safe parameters
| based on the properties available with these classes - e.g.
|
| MyFunction(Firstname="John")
| or
| MyFunction(classname, parameter=value)
|
| I imagined that to do this I would need to create a local instance of
| the relevent class (i.e. Contact) in the function and (possibly) use
| the param that's passed in the function call in a property setter call,
| but that's where I fell over really. Firstly because I won't know the
| name of the property to set (and didn't want to use a load of Select
| Cases) and secondly because it wouldn't enforce type-safety in the
| function call doing it this way).
|
| Firstly, is this possible? If so, how could I go about a) limiting the
| parameter that's passed to the function to those listed in the class
| enum, and secondly, is it possible to enforce the property-type of the
| passed parameter (i.e. if I pass a Firstname param, it will only accept
| a string, if I pass an Age param, it'll only accept an Int)?
|
| Sorry if these are stupid questions but I'm still trying to learn .Net
| and OOP.
|
| Thanks in advance
| Martin
|
 
J

Jay B. Harlow [MVP - Outlook]

Pritcham,
Doh! (clicked send too soon).

I should add that you could use straight reflection also, something like:

Private Sub MyFunction(ByVal theClass As String, ByVal theProperty As
PropertyList, ByVal theValue As Object)
Dim theType As Type = Type.GetType(theClass)
Dim theObject As Object = Activator.CreateInstance(theType)
Dim thePropertyType As System.Reflection.PropertyInfo =
theType.GetProperty(theProperty.ToString())
theValue = System.Convert.ChangeType(theValue,
thePropertyType.PropertyType)
thePropertyType.SetValue(theObject, theValue, Nothing)
End Sub

Watch the case of the property name, as GetProperty is normally case
sensitive. Alternatively you could use:

Dim thePropertyType As System.Reflection.PropertyInfo =
theType.GetProperty(theProperty.ToString(), Reflection.BindingFlags.Instance
Or Reflection.BindingFlags.Public Or Reflection.BindingFlags.IgnoreCase)


--
Hope this helps
Jay B. Harlow [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net


| Hi all
|
| I've got a number of classes already developed (basic entity classes)
| like the following:
|
| Public Class Contact
| Private _firstname as String
| Private _age as Integer
|
| Public Property FirstName As String
| Get
| Return Me._firstname
| End Get
| Set
| If (Me._firstname = value) Then
| Return
| End If
| Me._firstname = value
| End If
| End Set
| End Property
|
| Public Enum PropertyList
| FirstName,
| Age
| End Enum
|
| ....
|
| There are a number of classes like this that describe different
| entities (Company, User etc etc) - all of which have a public Enum that
| lists each available property for the entity.
|
| I need to write a (separate) function that takes type-safe parameters
| based on the properties available with these classes - e.g.
|
| MyFunction(Firstname="John")
| or
| MyFunction(classname, parameter=value)
|
| I imagined that to do this I would need to create a local instance of
| the relevent class (i.e. Contact) in the function and (possibly) use
| the param that's passed in the function call in a property setter call,
| but that's where I fell over really. Firstly because I won't know the
| name of the property to set (and didn't want to use a load of Select
| Cases) and secondly because it wouldn't enforce type-safety in the
| function call doing it this way).
|
| Firstly, is this possible? If so, how could I go about a) limiting the
| parameter that's passed to the function to those listed in the class
| enum, and secondly, is it possible to enforce the property-type of the
| passed parameter (i.e. if I pass a Firstname param, it will only accept
| a string, if I pass an Age param, it'll only accept an Int)?
|
| Sorry if these are stupid questions but I'm still trying to learn .Net
| and OOP.
|
| Thanks in advance
| Martin
|
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top