views:

55

answers:

5

Hello there, I have an object in csharp from the class Account each account have a owner, reference, etc.

One way I can access an accounts properties is through accessors like

account.Reference;

but I would like to be able to access it using dynamic string selectors like:

account["PropertyName"];

just like in javascript. so I would have account["Reference"] which would return the value...but I also would like to be able to sign a new value after that like:

account["Reference"] = "124ds4EE2s";

I've noticed I can use

DataBinder.Eval(account,"Reference") 

to get a property based on a string, but using this I can't sign a value to the property.

Any idea on how I could do that?

Thanks a lot

+2  A: 

First of all, you should avoid using this; C# is a strongly-typed language, so take advantage of the type safety and performance advantages that accompany that aspect.

If you have a legitimate reason to get and set the value of a property dynamically (in other words, when the type and/or property name is not able to be defined in the code), then you'll have to use reflection.

The most inline-looking way would be this:

object value = typeof(YourType).GetProperty("PropertyName").GetValue(yourInstance, null);
...
typeof(YourType).GetProperty("PropertyName").SetValue(yourInstance(yourInstance, "value", null);

However, you can cache the PropertyInfo object to make it more readable:

System.Reflection.PropertyInfo prop = typeof(YourType).GetProperty("PropertyName");

object value = prop.GetValue(yourInstance, null);
...
prop.SetValue(yourInstance, "value", null);
Adam Robinson
A: 

You need to use Reflection:

PropertyInfo property = typeof(Account).GetProperty("Reference");

property.SetValue(myAccount, "...", null);

Note that this will be very slow.

SLaks
A: 

If they are your own objects you could provide an indexer to access the fields. I don't really recommend this but it would allow what you want.

public object this[string propertyName]
{
    get
    {
        if(propertyName == "Reference")
            return this.Reference;
        else
            return null;
    }
    set
    {
        if(propertyName == "Reference")
            this.Reference = value;
        else
            // do error case here            
    }
}

Note that you lose type safety when doing this.

Stephan
A: 

I agree with the previous posters that you probably do need to be using the properties. Reflection is very slow compared to direct property access.

On the other hand, if you need to maintain a list of user-defined properties, then you can't use C# properties. You need to pretend you are a Dictionary, or you need to expose a property that behaves like a Dictionary. Here is an example of how you could make the Account class support user-defined properties:

public class Account
{
    Dictionary<string, object> properties;
    public object this[string propertyName]
    {
        get
        {
            if (properties.ContainsKey[propertyName])
                return properties[propertyName];
            else
                return null;
        }
        set
        {
            properties[propertyName] = value;
        }
    }
}
Paul Williams
A: 

You could try combining the indexer with reflection...

public object this[string propertyName] 
{ 
    get 
    { 
        PropertyInfo property = this.GetType().GetProperty(propertyName); 
        return property.GetValue(this, null); 

    } 
    set 
    { 
        PropertyInfo property = this.GetType().GetProperty(propertyName); 
        property.SetValue(this,value, null);     
    } 

}

Richard Friend