var, dynamic 差別以及如何實作像 ViewBag 一樣的物件【转】

原文:http://kelp.phate.org/2011/11/var-dynamic-viewbag.html

 

var

在以前寫程式時要宣告以及 Instance 的時候一般會寫成這樣。
1
TestModel model = new TestModel();
但從 C# 3.0 開始多了「var」,所以我們可以寫成這樣:
1
var model = new TestModel();
使用 var 的好處在於只需要打一次型別名稱。
var 宣告後的變數型別是固定的,未來程式在運作時無法改變型別(跟 JavaScript 不一樣),在程式撰寫時變數具有該型別的 IntelliSense。
說簡單一點就是「編譯器在編譯時會自動將 var 取代為適當的型別」。


dynamic

C# 4.0 多了「dynamic」,dynamic 跟 var 是截然不同的東西。
dynamic 允許在執行的過程替換變數的型別。
1
2
3
4
dynamic model = new TestModel();
model = new Exception();
model = 1;
//這樣的寫法不會造成 Exception
dynamic 還有一個特性就是編譯過程不會檢查值是否給對、呼叫的 method 是否存在、property 是否存在...等,而且 dynamic 沒有 IntelliSense。
筆者不太喜歡沒有 IntelliSense 的東西,因為很容易打錯字,所以沒必要的時候少用為妙。

有一點要注意的是:dynamic 變數存取不存在的 member、method 是為發生 Exception 的。
1
2
dynamic model = new Exception();
model.Title = "hello"; //執行的時候此行程式會出錯


ExpandoObject

在 MVC 3 的時候 Controller 可以透過 ViewBag 將資料傳給 View。
底下的程式就是透過 ViewBag 設定網頁的標題:
1
2
3
4
5
public ActionResult Index()
{
    ViewBag.Title = "Index";
    return View();
}
1
2
3
<head>
    <title>@ViewBag.Title</title>
</head>

ViewBag 就是一個 dynamic 的應用,而有些人可能會感覺很奇怪,就算是 dynamic 也不能存取不存在的 property,為什麼我可以丟任何的資料到 ViewBag 底下的任何一個 property 中。

其實 Instance ViewBag 的型別是 ExpandoObject,這個型別可以動態產生 property,所以才會有 ViewBag 這樣神奇的物件。
1
using System.Dynamic;
1
2
3
dynamic model = new ExpandoObject();
model.Title = "Index";
model.Time = DateTime.UtcNow;
 

 

另,试了一下在WCF中能不能用ExpandoObject来实现DTO的功能,结果被转化成了

System.Collections.Generic.Dictionary<string, object>,看来通过这种方式来避免使用DTO还是有一点问题。

不过这篇文章:Returning Dynamic Types from an Ajax Web Service Using C# 4.0 可以看到避免使用DTO的种可行性,但似乎是要在特定的WebService上以及使用Ajax来处理相应的响应(不可以是C#的代理类来处理匿名类型,否则会因为返回值是匿名类型会报异常)

 

 

posted @ 2012-05-31 09:50  吴东雷  阅读(797)  评论(0编辑  收藏  举报