总结:在不需要创建类而需要使用类结构的时候使用
一,ExpandoObject
使用场合
在传递对象,但是又不想创建一个class
或者struct
的时候,ExpandoObject
就是一个非常好的选择。
假如我们有一个SendMail
的函数,功能是发送一个通知邮件给客户,邮件的文本模板,如下:
Dear [Name],
We have sent the gift to your address: [Address]
在具体发送邮件的时候, [Name]
和[Address]
的内容是从函数GetMailParameters()
动态读取出来的。
那么函数GetMailParameters
的返回值如何定义好呢?
如果为GetMailParameters()
函数创建一个struct
或者class
来传递, 有些小题大做了,而且定义的struct
和class
重用性会非常低。
如果使用了ExpandoObject
, 就非常容易的解决了这个问题。
public dynamic GetMailParameters()
{
var mailParameters = new ExpandoObject();
mailParameters.Name=”Peter”;
mailParameters.Address=”Shanghai China”
return mailParamaters;
}
就算以后邮件模板改变,添加了新的变量,也只是简单的在ExpandoObject
上扩展一个属性就可以了。
二, 注意问题
由于ExpandObject
的先天不足(无特征性):
- 没有区分的类型名称
- 没有确切类型定义
如果你看到一个string
的函数返回值, 你会想到什么, 你会知道它是一个字符串(这不是废话吗?), 有Length
等属性,有IndexOf
等方法。
当返回值是MailHelper
类对象时,你想只需要直接F12就能看到源码,里面有关于这个类的详细定义,接着你就知道如何使用这个对象了。
当你从一个函数中得到一个ExpandObject
的dynamic
的返回值时,你知道是什么吗? ExpandObject
就是一个黑箱,里面装着什么,谁都不知道。
所以,
ExpandObject
不能用于太复杂的对象。
ExpandObject
最好还是作为简单的数据容器,不要弄得过于复杂,甚至包含有函数处理。
ExpandObject
的使用范围必须要短
范围短的意思是,产生和使用ExpandObject
的代码的路径必须要短(主要是函数调用路径)。如果你正在使用一个ExpandObject
对象,查看产生这个ExpandObject
的地方,发现分散在好几个函数之中,还有嵌套的话,那么这个ExpandObject
是非常难于维护的。
ExpandObject
的使用场合最好贴近程序的终端。
比如在MVC中的ViewBag
, 就是一个好的例子。ViawBag
用于生成页面, 而页面就是MVC程序的终端了。到了终端,ExpandObject
也就不能祸害它人了。
正是由于ExpandObject
的无特征性,什么都可以做,所以容易导致滥用。
深入理解 c# 第十四章 用ExpandoObject
存储和获取值
class SimpleExpando
{
static void Main()//用ExpandoObject 存储和获取值
{
dynamic expando = new ExpandoObject();
//{System.Dynamic.ExpandoObject}
IDictionary<string, object> dictionary = expando;
//{System.Dynamic.ExpandoObject}
expando.First = "value set dynamically";
Console.WriteLine(dictionary["First"]);
dictionary["Second"] = "value set with dictionary";
Console.WriteLine(expando.Second);
}
}
使用ExpandoObject
System.Dynamic.ExpandoObject
看上去像个古怪的野兽。它只有一个无参的公共构造函数。除了各个接口的显式实现外,它没有公共方法。比较重要的接口为IDynamicMetaObjectProvider
和IDictionary<string,object>
。(它实现的其他接口均为IDictionary<string,object)
所扩展的接口。) 它是封闭的,所以不能继承它从而实现有用的行为。只有用dynamic
引用或实现某个接口时,才能使用ExpandoObject
设置或获取单独的属性实现字典接口暗示了它的用途–通过名称存储对象。而这些名称也可以用作动态类型的属性。
将字符串作为字典的值。
输出
value set dynamically
value set with dictionary
动态属性ExpandoObject
1、动态创建对象及其属性ExpandoObject
查看ExpandoObject
的定义:
不难发现其实质是一个Dictionary
存放键值对,那么能否通过Dictionary
实现动态属性生成咧??