Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create properties automatically?

I have a "settings" class, which has some properties for usability and to restrict set accessor. It seems easy while i had within ten items, but then their count was increased. I need some way to create these properties automatically, something like that:

foreach(var property in SettingsList)
{
    _settings.AddAutoProperty(property);
}

It may have deal with reflection, but i can't get to efficient solution.

The properties definition:

public bool cbNextExcCount
{
    get { return (bool)this.GetValueById("cbNextExcCount"); }
}

public bool cbSaveOnChangeExc
{
    get { return (bool)this.GetValueById("cbSaveOnChangeExc"); }
}

public bool cbAutoIncrement
{
    get { return (bool)this.GetValueById("cbAutoIncrement"); }
}

public bool cbRememberOnExit
{
    get { return (bool)this.GetValueById("cbRememberOnExit"); }
}

...etc.

UPDATE To summ up, i wrote the next code:

public IDictionary<string, object> Properties = new ExpandoObject();
private List<string> SettingsList = new List<string> 
{ 
    "cbNextExcCount",
    "cbSaveOnChangeExc",
    "cbAutoIncrement",
    "cbRememberOnExit"
};

public void CreateProperties()
{
    foreach (string SettingName in SettingsList)
    {
        Properties.Add(SettingName, () => this.GetValueById(SettingName));
    }
}

But i have an error on () => this.GetValueById("cbNextExcCount")):

argument type 'lambda expression' is not assignable to parameter type 'object'.

I can store Func<bool>, but settings may have other type than bool and if i use Func, it's get a bit more complicate to call.

like image 502
LbISS Avatar asked Nov 06 '12 09:11

LbISS


2 Answers

You can't create auto-properties, but you can use an ExpandoObject.

I'm not sure if this is what you're looking for, because using expandos means using duck typing (i.e. dynamic programming).

ExpandoObject sample:

dynamic expando = new ExpandoObject();
expando.PropertyA = "Hello";
expando.PropertyB = "world!";

An interesting thing about expandos is that ExpandoObject implements IDictionary<string, object>, meaning that you can upcast any expando to this type and iterate over its added properties, which could be great for storing run-time created settings.

UPDATE

I was thinking more about a good solution and if SettingList is a custom class developed by yourself, maybe you can add a property called Custom to SettingList and add there settings that aren't added during design-time.

UPDATE 2

In your case, instead of storing the actual value of something, you could add Func<bool> to ExpandoObject's run-time settings:

IDictionary<string, object> settings = new ExpandoObject();
settings.Add("cbNextExcCount", () => this.GetValueById("cbNextExcCount"));

Actually, I don't know this scope in your code sample, but change this to anything that could be an instance of SettingList or whatever.

Once you've added run-time settings, you can type settings variable to dynamic typing in order to access properties like this:

dynamic allSettings = (dynamic)settings;
bool cbNextExcCount = allSettings.cbNextExcCount();
like image 62
Matías Fidemraizer Avatar answered Oct 10 '22 06:10

Matías Fidemraizer


You can consider Expando Objects in System.Dynamic namespace. This article can be a good start.

like image 36
Demir Avatar answered Oct 10 '22 04:10

Demir