evaluate a string to an object question

W

WebBuilder451

I have a custom business object of type Person.

i created a page with check boxes that will post to a second page that is
strongly typed with the first page and i have a function that retreives all
the checked boxes from the first page. The ID value of each checkbox is the
name of a property in the business object (Name, Address, Phone, ...). I can
get all the ids no problem here.

Question is there a way to convert or evaluate a string value to get an the
object property? ... So that:
Person PER = new Person(); // use default consrtructor here
string str = PER + ".Name"; will give me PER.Name?


Thanks
--
(i''ll be asking a lot of these, but I find C# totally way cooler than vb
and there''s no go''n back!!!)
thanks (as always)

kes
 
M

Marc Gravell

To do this you can either use reflection or System.ComponentModel, for
example:

PropertyDescriptorCollection props = TypeDescriptor.GetProperties(per);
string name = (string) props["Name"].GetValue(per);
int age = (int)props["Age"].GetValue(per);

etc

For more complex data there are a lot more things you can do...

Marc
 
G

Gilles Kohl [MVP]

I have a custom business object of type Person.

i created a page with check boxes that will post to a second page that is
strongly typed with the first page and i have a function that retreives all
the checked boxes from the first page. The ID value of each checkbox is the
name of a property in the business object (Name, Address, Phone, ...). I can
get all the ids no problem here.

Question is there a way to convert or evaluate a string value to get an the
object property? ... So that:
Person PER = new Person(); // use default consrtructor here
string str = PER + ".Name"; will give me PER.Name?

This is called reflection. First, you will need to get an object of
type "Type" that describes the class Person - this is done using
typeof(Person).

Then, use the GetProperty(string propertyName) method of the type
object to retrieve a PropertyInfo class by name.

Finally, use the GetValue method of the PropertyInfo class to get the
value for a given instance of "Person".

Since this is rather abstract, here is a concrete example that will
(hopefully) make things clearer:

using System;
using System.Reflection;

namespace ConsoleApplication1
{
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.FirstName = "Anders";
p.LastName = "Hjelsberg";

Type personType = typeof(Person);
string propertyToRetrieve = "FirstName";

PropertyInfo propertyInfo =
personType.GetProperty(propertyToRetrieve);

object retrievedValue = propertyInfo.GetValue(p, null);

Console.WriteLine("{0} = {1}", propertyToRetrieve,
retrievedValue);

Console.ReadKey();
}

}
}

Regards,
Gilles.
 
W

WebBuilder451

Very Much appreciated!!
--
(i''ll be asking a lot of these, but I find C# totally way cooler than vb
and there''s no go''n back!!!)
thanks (as always)

kes
 
W

WebBuilder451

Thank you it does make it very clear. Your help is also very appreciated!!

KES
--
(i''ll be asking a lot of these, but I find C# totally way cooler than vb
and there''s no go''n back!!!)
thanks (as always)

kes


Gilles Kohl said:
I have a custom business object of type Person.

i created a page with check boxes that will post to a second page that is
strongly typed with the first page and i have a function that retreives all
the checked boxes from the first page. The ID value of each checkbox is the
name of a property in the business object (Name, Address, Phone, ...). I can
get all the ids no problem here.

Question is there a way to convert or evaluate a string value to get an the
object property? ... So that:
Person PER = new Person(); // use default consrtructor here
string str = PER + ".Name"; will give me PER.Name?

This is called reflection. First, you will need to get an object of
type "Type" that describes the class Person - this is done using
typeof(Person).

Then, use the GetProperty(string propertyName) method of the type
object to retrieve a PropertyInfo class by name.

Finally, use the GetValue method of the PropertyInfo class to get the
value for a given instance of "Person".

Since this is rather abstract, here is a concrete example that will
(hopefully) make things clearer:

using System;
using System.Reflection;

namespace ConsoleApplication1
{
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}

class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.FirstName = "Anders";
p.LastName = "Hjelsberg";

Type personType = typeof(Person);
string propertyToRetrieve = "FirstName";

PropertyInfo propertyInfo =
personType.GetProperty(propertyToRetrieve);

object retrievedValue = propertyInfo.GetValue(p, null);

Console.WriteLine("{0} = {1}", propertyToRetrieve,
retrievedValue);

Console.ReadKey();
}

}
}

Regards,
Gilles.
 
C

Chris Shepherd

WebBuilder451 said:
I have a custom business object of type Person.

i created a page with check boxes that will post to a second page that is
strongly typed with the first page and i have a function that retreives all
the checked boxes from the first page. The ID value of each checkbox is the
name of a property in the business object (Name, Address, Phone, ...). I can
get all the ids no problem here.

Question is there a way to convert or evaluate a string value to get an the
object property? ... So that:
Person PER = new Person(); // use default consrtructor here
string str = PER + ".Name"; will give me PER.Name?

Maybe make your business object also a Dictionary, so you could expose business
properties, but also expose the index itself the way AppSettings are done?

Person PER = new Person();
string str = PER["Name"];

And in Person you have the name property like:
public string Name
{
get { return this["Name"]; }
set { this["Name"] = value; }
}

Saves you reflection, though I'm unsure of how performant/a good idea it is. If
AppSettings uses it though, it can't be too too horrible. :p

Chris.
 
M

Marc Gravell

The main issue with this type of approach is that you end up duplicating
everything - i.e. you have already declared various properties, but you
need to remember to add them into the indexer (or perhaps use reflection
in the default). Makes a bit of work, and note that the
System.ComponentModel approach I posted earlier is what most
data-binding uses under-the-hood, so it provides consistency.

In the case of AppSettings, there are no pre-defined values - it is
essentially a runtiome dictionary, so the indexer approach makes perfect
sense. The indexer also forces you to share a return type (although I
guess object would suffice).

Re your point on performance; by *default* yes, reflection and
System.ComponentModel are much slower than direct access, but if you are
going to be doing lots of this (i.e. bulk exports, etc), then with a few
tricks you can get the performance back up. Fortunately I've already
done those tricks ;-p
http://www.codeproject.com/KB/cs/HyperPropertyDescriptor.aspx

Marc
 
C

Chris Shepherd

Marc said:
The main issue with this type of approach is that you end up duplicating
everything - i.e. you have already declared various properties, but you
need to remember to add them into the indexer (or perhaps use reflection
in the default). Makes a bit of work, and note that the
System.ComponentModel approach I posted earlier is what most
data-binding uses under-the-hood, so it provides consistency.

Yeah, it is a downside, although the reflection-on-construction idea could
potentially provide better speed than reflection-on-access depending on number
of objects vs number of accesses.
In the case of AppSettings, there are no pre-defined values - it is
essentially a runtiome dictionary, so the indexer approach makes perfect
sense. The indexer also forces you to share a return type (although I
guess object would suffice).

Yeah, boxing all the return data to object could also introduce minor overhead
(something I hadn't considered).
Re your point on performance; by *default* yes, reflection and
System.ComponentModel are much slower than direct access, but if you are
going to be doing lots of this (i.e. bulk exports, etc), then with a few
tricks you can get the performance back up. Fortunately I've already
done those tricks ;-p
http://www.codeproject.com/KB/cs/HyperPropertyDescriptor.aspx

See, I forgot to add the *other* option was to just wait for Marc to post the
"real" solution. :p

That's actually pretty impressive performance.


Chris.
 

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