Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

string to variable name

Tags:

c#

I have class(Customer) which holds more than 200 string variables as property. I'm using method with parameter of key and value. I trying to supply key and value from xml file. For this, value has to be substituted by Customer class's property(string variables).

ie

Customer
{
  public string Name{return _name};

  public string Address{return _address};
}


CallInput
{
  StringTempelate tempelate = new StringTempelate();
  foreach(item in items)
  tempelate .SetAttribure(item.key, item.Value -->   //Say this value is Name, so it has to substitute Customer.Name
}

is it possible?

like image 990
Mohanavel Avatar asked Aug 18 '09 12:08

Mohanavel


4 Answers

You can use reflection to set the properties 'by name'.

using System.Reflection;
...
myCustomer.GetType().GetProperty(item.Key).SetValue(myCustomer, item.Value, null);

You can also read the properties with GetValue, or get a list of all property names using GetType().GetProperties(), which returns an array of PropertyInfo (the Name property contains the properties name)

like image 114
David Avatar answered Oct 16 '22 18:10

David


Well, you can use Type.GetProperty(name) to get a PropertyInfo, then call GetValue.

For example:

// There may already be a field for this somewhere in the framework...
private static readonly object[] EmptyArray = new object[0];

...

PropertyInfo prop = typeof(Customer).GetProperty(item.key);
if (prop == null)
{
    // Eek! Throw an exception or whatever...
    // You might also want to check the property type
    // and that it's readable
}
string value = (string) prop.GetValue(customer, EmptyArray);
template.SetTemplateAttribute(item.key, value);

Note that if you do this a lot you may want to convert the properties into Func<Customer, string> delegate instances - that will be much faster, but more complicated. See my blog post about creating delegates via reflection for more information.

like image 28
Jon Skeet Avatar answered Oct 16 '22 18:10

Jon Skeet


Reflection is an option, but 200 properties is... a lot. As it happens, I'm working on something like this at the moment, but the classes are created by code-gen. To fit "by name" usage, I've added an indexer (during the code generation phase):

public object this[string propertyName] {
    get {
        switch(propertyName) {
            /* these are dynamic based on the the feed */
            case "Name": return Name;
            case "DateOfBirth": return DateOfBirth;
            ... etc ...
            /* fixed default */
            default: throw new ArgumentException("propertyName");
        }
    }
}

This gives the convenience of "by name", but good performance.

like image 40
Marc Gravell Avatar answered Oct 16 '22 17:10

Marc Gravell


Use reflection and a dictionary object as your items collection.

Dictionary<string,string> customerProps = new Dictionary<string,string>();
Customer myCustomer = new Customer(); //Or however you're getting a customer object

foreach (PropertyInfo p in typeof(Customer).GetProperties())
{
    customerProps.Add(p.Name, p.GetValue(customer, null));
}
like image 24
MattH Avatar answered Oct 16 '22 17:10

MattH