C# 的 dynamic 关键字可以是C#可以像 javascript 这种弱类型语言一样具有随时可以添加属性的能力。C# 是一种强类型语言,dynamic 要摆脱类型的限制,自然是有代价的。这里不讨论CPU做了多少额外的工作使得 C# 具有了超脱其天性的能力。然而这种能力会简化我们的编程。在项目开发中给我带来的实实在在的好处就是减少创建模型类。
分享一下 dynamic 应用
在做 web 项目时,有时候页面上的某个角落要显示一些简单的信息,或者一些下拉框里的信息等等。这些信息的信息量小,用的地方少。为了获取这些信息专门定义一个 Class 有点不值得,而且增加了我们模型类的数量,看着那么多模型类就烦。 dynamic 关键词可以很好的解决这个问题。
代码如下:
1 /// <summary> 2 /// 返回动态类型的数据。 3 /// </summary> 4 /// <returns></returns> 5 private dynamic DynamicInfo() 6 { 7 dynamic item = null; 8 List<ExpandoObject> li = new List<ExpandoObject>(); 9 for (var i = 65; i < 91; i++) 10 { 11 item = new ExpandoObject(); 12 item.数字 = i;//为动态类型添加信息 13 item.字母 = string.Format("{0}", (Char)i);//为动态类型添加信息 14 li.Add(item); 15 } 16 return li; 17 }
怎么把这些动态信息返回到客户端呢?当然是序列化成json格式,通过 jQuery 的 ajax 功能很容易获取到。下面是mvc4里的实现:
1 public JsonResult GetDynamicInfo() 2 { 3 return Json(DynamicInfo(), JsonRequestBehavior.AllowGet); 4 }
客户端获取服务器端数据,并将数据以表格的形式显示的在客户端:
1 $.getJSON("/Home/GetDynamicInfo", function (data) { 2 if (data && data.length > 0) { 3 var table = document.createElement("table"), tr, td, text; 4 tr = document.createElement("tr"); 5 table.appendChild(tr); 6 for (var b = 0; b < data[0].length; b++) { 7 td = document.createElement("td"); 8 text = document.createTextNode(data[0][b].Key); 9 td.appendChild(text); 10 tr.appendChild(td); 11 } 12 for (var a = 0; a < data.length; a++) { 13 tr = document.createElement("tr"); 14 table.appendChild(tr); 15 for (var b = 0; b < data[a].length; b++) { 16 td = document.createElement("td"); 17 text = document.createTextNode(data[a][b].Value); 18 td.appendChild(text); 19 tr.appendChild(td); 20 } 21 } 22 document.body.appendChild(table); 23 } 24 });
显示效果如下,当然有点简陋:
上面分享了从服务器端到客户端的整个过程,可以看到利用动态类型,我们并没有建立一个具有数字,字母两个字段的模型类。
关于 dynamic
dynamic 类型定义的代码,在编译期间不会进行类型检查,编译器假定给 dynamic 类型定义的对象的任何操作都是正确的。 dynamic 与 var 这两个关键词是不一样的。var 关键词定义的对象只是延迟确定其类型,类型一旦确定,就不能再改变了。而 dynamic 定义的类型在运行期间可以多次被改变。为什么呢,很简单,因为 dynamic 类型的对象是在运行期间根据程序的静态代码信息确定的,也就是在编写代码时定义了多少种类型,那么运行期间就可以确定出对应的类型。例如:
1 dynamic d = 0; 2 d = "change to a string."; 3 d = 'a';
运行期间,就可以计算出对象 d 依次是 int, string, char.
dynamic 为我们的编程带来方便的同时,也是以牺牲了一部分性能为代价的。查看 dynamic 类型的代码生成的 IL,会发现编译器做了很多的工作。
查看第一部分分享应用的代码,会发现用了一个 ExpandoObject 类。这个类微软定义的应用动态类型的辅助类,是一个密封类,继承自 DynamicObject。 当然在使用动态类型时,也可以直接使用 DynamicObject,但是要做很多的工作去实现类似 ExpandoObject 实现的工作。既然微软已经有现成的,那么就用现成的吧。