Use reflection to find out property name?

  • Thread starter Thread starter Nemisis
  • Start date Start date
N

Nemisis

Hi everyone,

Can anyone tell me if it is possible to pass in a property of an object
into a sub, and within that sub, find out the name of the item that was
passed along with the property name??

Example would be

......Code
Dim ObjA As New ObjectA

Me.CallSub(ObjA.Name)

Then within the sub, it should work out that the object passed in was
of type ObjectA, and the property was Name.

Is this possible? Cna someone point me in the right direction, or an
article i can read.

The reason i would like to do this is because i have giving users
access to renaming in my application, and the names are based on Table
fields at the moment, but i would like to move this to the class and
property instead.

Thanks
 
Hi Nemesis,

It is not possible to know what created a specific object, just by looking
at the object. If you have ObjectA and ObjectB and Name occurs in only
one of them you can compare Name against known values and thereby
determine if it comes from ObjectA or ObjectB, but this will not work if
Name occurs in both classes.

Why don't you pass ObjA instead of ObjA.Name and let CallSub get the name,
assuming all objects have the Name property.

If ObjA is of type PropertyInfo, then you can find the type this property
belongs to by using PropertyInfo.ReflectedType
 
Morten said:
Hi Nemesis,

It is not possible to know what created a specific object, just by looking
at the object. If you have ObjectA and ObjectB and Name occurs in only
one of them you can compare Name against known values and thereby
determine if it comes from ObjectA or ObjectB, but this will not work if
Name occurs in both classes.

Why don't you pass ObjA instead of ObjA.Name and let CallSub get the name,
assuming all objects have the Name property.

If ObjA is of type PropertyInfo, then you can find the type this property
belongs to by using PropertyInfo.ReflectedType

Morten,
This is not an option, because each object will have at least 20
properties each and each one can be renamed by the user.

So there is no possible way to pass in an object and property (ie.
ObjA.Name) and figure out that the object being passed is of type
"ObjectA" and the property is "Name"?

Is there no way of passing in ObjA.Name and converting that into a
string, without actually passing in "ObjectA.Name"?

I need to be able to then compare the string ie. ObjectA.Name in the
database and see what the user has named it.
 
Morten,
This is not an option, because each object will have at least 20
properties each and each one can be renamed by the user.

So there is no possible way to pass in an object and property (ie.
ObjA.Name) and figure out that the object being passed is of type
"ObjectA" and the property is "Name"?

Is there no way of passing in ObjA.Name and converting that into a
string, without actually passing in "ObjectA.Name"?

I need to be able to then compare the string ie. ObjectA.Name in the
database and see what the user has named it.

A string does not have a backward references to say who it belongs to, so
you can't look back to see the 'owning' object.
When you 'pass in ObjA.Name' you are not passing ObjA at all, simply a
reference to a string. You're not even passing in 'Name', as your string
might be referenceed by many other variables and/or properties.

You can pass in a reference to ObjA and a string with the name of the
property to use, then use TypeOf to get the object type and reflection to
get the type of property and its value. Properties such as DisplayMember on
data-bound components refer to properties in this way. This is however
relatively slow, so choose your solution wisely :)

Cheers,
Gadget
 
Gadget said:
A string does not have a backward references to say who it belongs to, so
you can't look back to see the 'owning' object.
When you 'pass in ObjA.Name' you are not passing ObjA at all, simply a
reference to a string. You're not even passing in 'Name', as your string
might be referenceed by many other variables and/or properties.

You can pass in a reference to ObjA and a string with the name of the
property to use, then use TypeOf to get the object type and reflection to
get the type of property and its value. Properties such as DisplayMember on
data-bound components refer to properties in this way. This is however
relatively slow, so choose your solution wisely :)

Cheers,
Gadget

Gadget,
Thanks for the info, that very helpful. I was wondering, since you
know what i am trying to do, i didnt know if this was the best option,
or maybe create a custom attribute for each property, that would return
a screen name, that the user has renamed it too?

Could this work? How many attributes can you have on a property? Or
is this a bad idea?
 
Gadget,
Thanks for the info, that very helpful. I was wondering, since you
know what i am trying to do, i didnt know if this was the best option,
or maybe create a custom attribute for each property, that would return
a screen name, that the user has renamed it too?

Could this work? How many attributes can you have on a property? Or
is this a bad idea?

Well to be honest, I'm not quite sure what you are trying to do :)
You mention that properties can be renamed, but does that mean your users
are recompiling their code? Are you creating a library for developers to
include?
Are you trying to create a generic business object system that maps to a
database table or something?
If you can give a brief synopsis of what and why you're doing it then I can
try and help (or even suggest some alternative approaches) :)

Cheers,
Gadget
 
Gadget said:
Well to be honest, I'm not quite sure what you are trying to do :)
You mention that properties can be renamed, but does that mean your users
are recompiling their code? Are you creating a library for developers to
include?
Are you trying to create a generic business object system that maps to a
database table or something?
If you can give a brief synopsis of what and why you're doing it then I can
try and help (or even suggest some alternative approaches) :)

Cheers,
Gadget

Gadget,

Sorry probably not explained it that well.

I have made all my business objects, but the web site allows for users
to rename the properties. This is not done by recompiling code, i have
a table in my database that has a list of the classes and properties
stored as strings (ie. Company.Name). And then i have two fields
called Singular and plural so users can type the string that they want
to appear next to the property.

Example

If i had Company.Name stored in one field, the singular could be
"Company Name" and the plural "Company Names". On the website, a label
control would appear next to the value of the property.

Company Name = COMPANY NAME HERE

Does this make sense??
 
Gadget,

Sorry probably not explained it that well.

I have made all my business objects, but the web site allows for users
to rename the properties. This is not done by recompiling code, i have
a table in my database that has a list of the classes and properties
stored as strings (ie. Company.Name). And then i have two fields
called Singular and plural so users can type the string that they want
to appear next to the property.

Example

If i had Company.Name stored in one field, the singular could be
"Company Name" and the plural "Company Names". On the website, a label
control would appear next to the value of the property.

Company Name = COMPANY NAME HERE

Does this make sense??

Yes, I think I understand. So the database row primary key is a combination
of the class name and the property name, and the rows in this table should
be created once after you have compiled your application, as they remain
static throughout a single version of your application because the classes
are obviously non-changing.

So presumably you only need to know the associated class and properties
when a form is being displayed. This means that during the Load event or
constructor you plan to look at all the labels on the screen and find the
associated values from the database?
What ties an input field on the form to a particular property of an object?
Are you using form data-binding? There has to be something that relates the
label associated with an input control to the business object and property
it is associated with, and there is not really any generic or magic way to
do this. If you are planning on using a DataGrid, and want to automatically
set the column names, then this is probably best done by defining a static
method and calling it, passing in the DataGrid instance and the class type.

A sensible way to handle discrete controls on a form might be to inherit
from a Label component, say to a 'PersonalizedLabel', add string properties
of "AppliesToClass" and "AppliesToProperty", then during the load event
have each lookup the new label value and set it in the Text property.

Also for performance make sure that during the application startup you load
the contents of your labels into a cache class (e.g. Dictionary<string,
LabelRowDetails>) so you can lookup controls on every form load without any
database access.

Might I also suggest that perhaps you should add another column denoting
the use of the class on the form, because if you use the same class in two
locations (e.g. On a customer form, where a field might be called "Name:",
and on an administration form where your customer might call it "Customer
Name:") then it would be nice to build in the option of 'switching' labels
for special circumstances. This might not happen, but for 30secs of work
now it might save you many hours later :)

Just a few thoughts and observations, and I don't know if I've missed the
point somewhere here :)

Cheers,
Gadget
 
Back
Top