【问题标题】:How to create properties automatically?如何自动创建属性?
【发布时间】:2012-10-26 05:43:43
【问题描述】:

我有一个“设置”类,它具有一些可用性和限制设置访问器的属性。当我有十件以内的物品时,这似乎很容易,但后来它们的数量增加了。我需要一些方法来自动创建这些属性,就像这样:

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

但我在() =&gt; this.GetValueById("cbNextExcCount")) 上有一个错误:

参数类型“lambda 表达式”不可分配给参数类型“对象”。

我可以存储Func&lt;bool&gt;,但设置可能有其他类型而不是 bool,如果我使用 Func,调用起来会有点复杂。

【问题讨论】:

  • 属性的标准是什么?以“cb”开头?
  • @AmiramKorach 的匈牙利语形式导致所有人鄙视它(与原始形式相反,有些人仍然捍卫)“cb”表示类级别的布尔值,当然这很明显在这里毫无意义。
  • cb 是否意味着后面有复选框?如果是的话,你不使用某种数据绑定是什么?你应该描述你想要做什么,而不仅仅是如何。我觉得会有比你的更简单优雅的解决方案。
  • 您不能在运行时动态创建属性并在代码中静态使用它们...您是否尝试在设计/编译时生成属性?
  • "cb" 表示复选框,还有其他属性(用于组合框等),所以不能动态创建属性。很遗憾,但我并不真正喜欢数据绑定,所以最好了解更多关于它的信息,也许我会找到解决方案。

标签: c# .net reflection properties


【解决方案1】:

您不能创建自动属性,但可以使用ExpandoObject

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

ExpandoObject 样本:

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

关于 expandos 的一个有趣之处在于 ExpandoObject 实现了 IDictionary&lt;string, object&gt;,这意味着您可以将任何 expando 向上转换为这种类型并迭代其添加的属性,这对于存储运行时创建的设置非常有用。

更新

我在想一个好的解决方案,如果SettingList 是您自己开发的自定义类,也许您可​​以将一个名为Custom 的属性添加到SettingList 并添加设计期间未添加的设置-时间。

更新 2

在您的情况下,您可以将Func&lt;bool&gt; 添加到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();

【讨论】:

  • ) 在您编写更新 2 之前,我已经尝试存储 Func(bool),如下所示:settings.cbNextExcCount = new Func(() => (bool)this.GetValueById( "cbNextExcCount"));但是,如果我尝试使用您的代码,我在“() => this.GetValueById("cbNextExcCount"))”上有一个错误:参数类型“lambda 表达式”不可分配给参数类型“对象”
  • @LblSS BTW,请检查我在回答中是如何做到的。我正在向上转换为IDictionary&lt;string, object&gt;
  • @LblSS 其他细节:您不需要将值转换为 bool,因为您使用的是动态类型。没用,因为类型检查会在运行时进行。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2017-09-30
    • 1970-01-01
    • 2012-12-20
    • 2014-03-19
    • 1970-01-01
    • 2018-07-03
    • 2012-02-01
    • 1970-01-01
    相关资源
    最近更新 更多