94

What I'm trying to do is setting the value of the property in a class using a string. For example, my class has the following properties:

myClass.Name
myClass.Address
myClass.PhoneNumber
myClass.FaxNumber

All the fields are of string type so I know ahead of time that it's always a string. Now, I want to be able to set the properties using a string as you could do with a DataSet object. Something like this:

myClass["Name"] = "John"
myClass["Address"] = "1112 River St., Boulder, CO"

Ideally, I want to just assign a variable and then set the property using that string name from the variable:

string propName = "Name"
myClass[propName] = "John"

I was reading about reflection and maybe it's the way to do it but I'm not sure how to go about setting that up while keeping the property access intact in the class. I want to still be able to use:

myClass.Name = "John"

Any code examples would be really great.

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
Patratacus
  • 1,651
  • 1
  • 16
  • 19
  • Look at that too: http://stackoverflow.com/questions/279374/how-do-i-use-net-reflection-to-search-for-a-property-by-name-ignoring-case – MarcinJuraszek Apr 23 '12 at 15:13
  • I'm trying to do this because I'm getting the data dump from the data base and I'm only selectively wanting to pick out the fields I need to store in my class. Basically I don't want to do a check for each item and store in the class. I need to loop through all the fields and only pick out and add the item to the class dynamically. – Patratacus Apr 23 '12 at 16:04
  • Look at https://stackoverflow.com/questions/1196991/get-property-value-from-string-using-reflection-in-c-sharp/24919811#24919811 – Eduardo Cuomo Feb 26 '19 at 15:47

3 Answers3

158

You can add indexer property, a pseudocode:

public class MyClass 
{
     public object this[string propertyName] 
     {
        get
        {
           // probably faster without reflection:
           // like:  return Properties.Settings.Default.PropertyValues[propertyName] 
           // instead of the following
           Type myType = typeof(MyClass);                   
           PropertyInfo myPropInfo = myType.GetProperty(propertyName);
           return myPropInfo.GetValue(this, null);
        }
        set
        {
           Type myType = typeof(MyClass);                   
           PropertyInfo myPropInfo = myType.GetProperty(propertyName);
           myPropInfo.SetValue(this, value, null);
        }
     }
}
wonea
  • 4,783
  • 17
  • 86
  • 139
Tigran
  • 61,654
  • 8
  • 86
  • 123
  • 1
    You, my friend, are an absolute genius! Thank you! – Christopher Smit Jan 06 '20 at 10:57
  • 3
    Nice! I would suggest replacing `typeof(MyClass)` with just `GetType()` to make it more generic, if it is used in abstract class for an example. :) – Jackie Feb 24 '20 at 15:35
  • Nice solution! But won't work with properties as Dictionary type, Visual Studio points error when trying to add a value - no definition for Add. Thought is limited to set the value, so there is a workaround that is creating a temporary dictionary 'D' and set de value as 'D'. – Gustavo May 06 '20 at 19:24
  • Is there something similar for `static` classes? – Homer May 24 '23 at 17:16
6

You can add an indexer to your class and use reflection to aces the properties:

using System.Reflection;

public class MyClass {

    public object this[string name]
    {
        get
        {
            var properties = typeof(MyClass)
                    .GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (var property in properties)
            {
                if (property.Name == name && property.CanRead)
                    return property.GetValue(this, null);
            }

            throw new ArgumentException("Can't find property");

        }
        set {
            return;
        }
    }
}
Dennis Traub
  • 50,557
  • 7
  • 93
  • 108
-3

May be something like this?

    public class PropertyExample
{
    private readonly Dictionary<string, string> _properties;

    public string FirstName
    {
        get { return _properties["FirstName"]; }
        set { _properties["FirstName"] = value; }
    }

    public string LastName
    {
        get { return _properties["LastName"]; }
        set { _properties["LastName"] = value; }
    }
    public string this[string propertyName]
    {
        get { return _properties[propertyName]; }
        set { _properties[propertyName] = value; }
    }

    public PropertyExample()
    {
        _properties = new Dictionary<string, string>();
    }
}
Deitro
  • 255
  • 2
  • 10