将未知(在devise时间)属性添加到ExpandoObject

只是探索C#4.试图让我的头在所有这些dynamic的东西。 对不起,如果这个问题是愚蠢的,在这个领域没有经验。

如果我有一个ExpandoObject,并且希望在运行时为它添加公共属性(如get和set),我将如何去做呢?

例如,我有一个documentTemplate和一个文档,它有一个指向documentTemplate的属性。 这个文档模板有一些标签标题(例如,在学生中开发的function),这些文档在制作文档时应该加以说明(例如浓度,记忆等)。 所以,只要在文档中设置模板,我想要创build一个类,它具有与模板中的标签名称相同的属性,然后使用一些UI元素,如PropertyGrid,我可以让用户根据标签标题填写标签值。

谢谢阅读!

我想知道如何能够“dynamic”地将一个成员添加到一个类中,并提出这个例子:

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

这个代码片断的重点是,成员A和B被定义为string文字(硬编码/string化),并通过ExpandoObject的IDictionary接口添加。 我们通过直接访问它们并输出到控制台来testing密钥的存在和值(并certificate这个概念)。

可以将委托属性添加到ExpandoObject ,然后(几乎)就像方法一样。 例如,

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

是的,ExpandoObject的devise非常强大,可以dynamic地将属性添加到“属性包”中。 然而,不支持给予这样的财产一个吸气和二传手的概念。 如果你想一下,也许这就清楚了:如果你已经知道吸气和吸气装置应该做什么,它就不再是一个dynamic属性了。 您可以得到最接近的实现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); } } 

到目前为止的答案涵盖了基础知识相当好,但我觉得这个MSDN杂志的文章也值得分享:

http://msdn.microsoft.com/en-us/magazine/ff796227.aspx

它涵盖了使用dynamicXMLinputdynamic创build和使用ExpandoObjects的一些示例。

我刚刚发现了这个有趣的事实: 对ExpandoObject的XAML绑定也将创build绑定尝试访问的属性

我仍然需要更多的创造力来找出这可能是有益的。 在UI上创builddynamic对象? 听起来很酷:DI会尝试一些东西。