C# 向ExpandooObject添加未知(设计时)属性

C# 向ExpandooObject添加未知(设计时)属性,c#,c#-4.0,expandoobject,C#,C# 4.0,Expandoobject,只是在探索c#4。试着让我的头脑了解这些动态的东西。对不起,如果这个问题很傻,没有这个领域的经验 如果我有一个ExpandoObject,并且希望在运行时向它添加公共属性(使用get和set),我将如何进行呢 例如,我有一个documentTemplate和一个document,其中有一个指向documentTemplate的属性。此文档模板有一些标签标题(例如,在学生中培养的能力),在制作文档时应注明这些标题(例如,注意力、记忆力等)。因此,一旦在文档中设置了模板,我就要创建一个类,该类的属性

只是在探索c#4。试着让我的头脑了解这些动态的东西。对不起,如果这个问题很傻,没有这个领域的经验

如果我有一个ExpandoObject,并且希望在运行时向它添加公共属性(使用get和set),我将如何进行呢

例如,我有一个documentTemplate和一个document,其中有一个指向documentTemplate的属性。此文档模板有一些标签标题(例如,在学生中培养的能力),在制作文档时应注明这些标题(例如,注意力、记忆力等)。因此,一旦在文档中设置了模板,我就要创建一个类,该类的属性与模板中的标记标题同名,然后使用一些UI元素,例如PropertyGrid,我可以让用户根据标记标题填写标记值


谢谢你的阅读

是的,ExpandoObject的设计非常适合动态地将属性添加到“属性包”。但是,不支持为此类属性指定getter和setter的概念。如果你想一想,也许这一点很清楚:如果你已经知道getter和setter应该做什么,那么它就不再是一个动态属性了。最接近的方法是实现INotifyPropertyChanged事件,以便检测更改。一些示例代码:

using System;
using System.Dynamic;
using System.ComponentModel;

class Program {
  static void Main(string[] args) {
    dynamic obj = new ExpandoObject();
    obj.test = 42;     // Add a property
    Console.WriteLine(obj.test);

    var inpc = (INotifyPropertyChanged)obj;
    inpc.PropertyChanged += inpc_PropertyChanged;
    obj.test = "foo";
    Console.ReadLine();
  }

  static void inpc_PropertyChanged(object sender, PropertyChangedEventArgs e) {
    Console.WriteLine("'{0}' property changed", e.PropertyName);
  }

}

可以将委托属性添加到
ExpandoObject
,然后这些属性的行为(几乎)与方法类似。e、 g

dynamic obj = new ExpandoObject();
obj.GetDocumentTemplate = () => { ... };
...
obj.GetDocumentTemplate(); // invokes delegate

我想知道如何才能将成员添加到“动态”的类中,并给出了以下示例:

using System;
using System.Collections.Generic;
using System.Dynamic;

class Program
{
    static void Main()
    {
        dynamic expando = new ExpandoObject();
        var p = expando as IDictionary<String, object>;

        p["A"] = "New val 1";
        p["B"] = "New val 2";

        Console.WriteLine(expando.A);
        Console.WriteLine(expando.B);
    }
}
使用系统;
使用System.Collections.Generic;
运用系统动力学;
班级计划
{
静态void Main()
{
动态expando=新的ExpandoObject();
var p=作为索引的expando;
p[“A”]=“新值1”;
p[“B”]=“新值2”;
控制台写入线(expando.A);
控制台写入线(expando.B);
}
}

此代码段的要点是,成员A和B在中定义为字符串文字(硬编码/字符串化),并通过ExpandooObject的IDictionary接口添加。我们通过直接访问密钥并将其输出到控制台来测试密钥的存在性和值(并证明其概念)。

到目前为止,答案涵盖了基本知识,但我觉得这篇MSDN杂志文章也值得分享:


本文介绍了一些使用动态XML输入动态创建和使用ExpandoObjects的示例

我刚刚发现了一个有趣的事实:到ExpandoObject的XAML绑定也将创建绑定试图访问的属性


我仍然需要更多的创造力来发现这有什么好处。在UI上创建动态对象?听起来很酷:我要试试

谢谢你的解释和代码。然而,我的问题略有不同。我想知道是否可以在运行时添加“test”属性?我的意思是,在设计时我们甚至不知道酒店的名称。类似于:obj.SetProperty(stringVariable)=另一个stringVariable.Erm,不。你为什么不简单地使用字典?这样我就可以轻松地绑定到Windows窗体。我只是想补充一点,我阅读了这篇关于ExpandooObject的文章的死树版本:不确定它是否回答了你的问题,但这对我来说是一个伟大的开端。无法将带[]的索引应用于“System.Dynamic.ExpandooObject”类型的表达式。有什么想法吗?@JasonFoglia:有。请将此作为问题发布,并显示一些代码,包括输入和预期输出。我们只能从评论中猜测可能发生的事情……你是虐待狂:-)