如何自动创建属性?

时间:2012-11-06 09:36:27

标签: c# .net reflection properties

我有一个“设置”类,它具有一些可用性属性和限制set访问器。我有10个项目似乎很容易,但随后他们的数量增加了。我需要一些方法来自动创建这些属性,如下所示:

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

它可能涉及反思,但我无法得到有效的解决方案。

属性定义:

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.

更新 总结一下,我写了下一个代码:

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));
    }
}

但我在() => this.GetValueById("cbNextExcCount"))上发生错误:

参数类型'lambda expression'不能赋值给参数类型'object'。

我可以存储Func<bool>,但设置可能有其他类型而不是bool,如果我使用Func,则调用会更复杂。

2 个答案:

答案 0 :(得分:8)

您无法创建自动属性,但可以使用ExpandoObject

我不确定这是否是你要找的,因为使用expandos意味着使用 duck typing (即动态编程)。

ExpandoObject示例:

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

有关expandos的一个有趣的事情是ExpandoObject实现了IDictionary<string, object>,这意味着您可以将任何expando转换为此类型并迭代其添加的属性,这对于存储运行时创建的设置非常有用

<强>更新

我正在考虑更好的解决方案,如果SettingList是您自己开发的自定义类,也许您可​​以向Custom添加名为SettingList的属性并添加那些设置在设计时添加。

更新2

在您的情况下,您可以将Func<bool>添加到ExpandoObject的运行时设置,而不是存储某些内容的实际值:

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

实际上,我不知道代码示例中的this范围,而是将this更改为可能是SettingList或其他任何实例的任何内容。

添加运行时设置后,您可以键入settings变量到dynamic键入,以便访问以下属性:

dynamic allSettings = (dynamic)settings;
bool cbNextExcCount = allSettings.cbNextExcCount();

答案 1 :(得分:1)

您可以考虑System.Dynamic命名空间中的Expando对象。 This文章可以是一个好的开始。