如果你用MVC寫過程式,那麼你應該知道ViewBag這個用於前後臺的數據傳遞工具,那麼你是否對ViewBag的用法感到過疑惑呢? 我們知道,在使用對象屬性的時候要先申明(即這個對象的類中已經定義了這個屬性)才能使用(此時VS的自動提示能彈出此類的所有屬性),然而使用ViewBag時你會發現 View ...
如果你用MVC寫過程式,那麼你應該知道ViewBag這個用於前後臺的數據傳遞工具,那麼你是否對ViewBag的用法感到過疑惑呢?
ViewBag.Mode1l=new object(); ViewBag.Model2=new object(); ViewBag.Model3=new object(); ......
我們知道,在使用對象屬性的時候要先申明(即這個對象的類中已經定義了這個屬性)才能使用(此時VS的自動提示能彈出此類的所有屬性),然而使用ViewBag時你會發現 ViewBab. 之後不會彈出任何屬性(除非前面已經添加了屬性),而且我們可以自己隨便寫一個屬性,卻可以正確運行。而這都是歸功於dynamic這個屬性。
1.在講dynamic之前,先來回顧一下var這個類型。
從 Visual C# 3.0 開始,在方法範圍中聲明的變數可以具有隱式類型 var。 隱式類型的本地變數是強類型變數(就好像您已經聲明該類型一樣),但由編譯器確定類型。 下麵的兩個 i 聲明在功能上是等效的:
var i = 10; // implicitly typed(隱式申明) int i = 10; //explicitly typed(顯示申明)
var這個類型是通過編譯器確定的(即在編譯時,編譯器會根據這個變數的值或引用的對象類型來決定這個變數的類型),但要註意一旦這個變數的類型確定了之後就不可在更改。
var i = 1; //i為int型 , 等價於 int i = 1; i = 1.0; //報錯,1.0為double型
註意,var型變數在申明時必須初始化,如下:
var i = 1; //正確 var i; i = 1; //錯誤
2.var用法舉例:
// 允許但不需要使用var,因為可以將查詢結果的類型顯示的申明為IEnumerable<string> string[] words = { "apple", "strawberry", "grape", "peach", "banana" }; var wordQuery = from word in words where word[0] == 'g' select word; // 因為元素類型為string類型,不是匿名類型,所以var是非必需的 foreach (string s in wordQuery) { Console.WriteLine(s); } //var must be used because the result is a collection of anonymous types, and the name of that type is not accessible except to the compiler itself.">表達式中必須使用 var,因為結果是一個匿名類型集合,而該類型的名稱只有編譯器本身可以訪問 var custQuery = from cust in customers where cust.City == "Phoenix" select new { cust.Name, cust.Phone }; //foreach iteration variable item must also be implicitly typed.">foreach 迭代變數 item 也必須轉換為隱式類型,因為custQuery為匿名集合 foreach (var item in custQuery) { Console.WriteLine("Name={0}, Phone={1}", item.Name, item.Phone); }
3.dynamic
在通過 dynamic 類型實現的操作中,該類型的作用是繞過編譯時類型檢查, 改為在運行時解析這些操作。 dynamic 類型簡化了對 COM API(例如 Office Automation API)、動態 API(例如 IronPython 庫)和 HTML 文檔對象模型 (DOM) 的訪問。
在大多數情況下,dynamic 類型與 object 類型的行為是一樣的。 但是,不會用編譯器對包含 dynamic 類型表達式的操作進行解析或類型檢查。 編譯器將有關該操作信息打包在一起,並且該信息以後用於計算運行時操作。 在此過程中,類型 dynamic 的變數會編譯到類型 object 的變數中。 因此,類型 dynamic 只在編譯時存在,在運行時則不存在。
class Program { static void Main(string[] args) { dynamic dyn = 1; object obj = 1; dyn = dyn + 3; //編譯可以通過,dynamic可以繞過編譯器 obj = obj + 3; //報錯,編譯無法通過 System.Console.WriteLine(dyn.GetType()); System.Console.WriteLine(obj.GetType()); } } //輸出結果 System.Int32 System.Int32
4.dynamic一些常見的用法
(1)在聲明中,作為屬性、欄位、索引器、參數、返回值或類型約束的類型。
class ExampleClass { // 欄位 static dynamic field; // 屬性 dynamic prop { get; set; } //返回值與參數 public dynamic exampleMethod(dynamic d) { dynamic local = "Local variable"; int two = 2; if (d is int) { return local; } else { return two; } } }
(2)在顯式類型轉換中,作為轉換的目標類型。
static void convertToDynamic() { dynamic d; int i = 20; d = (dynamic)i; Console.WriteLine(d); string s = "Example string."; d = (dynamic)s; Console.WriteLine(d); DateTime dt = DateTime.Today; d = (dynamic)dt; Console.WriteLine(d); } // Results: // 20 // Example string. // 2/17/2009 9:12:00 AM
(3)在以類型充當值(如 is 運算符或 as 運算符右側)或者作為 typeof 的參數成為構造類型的一部分的任何上下文中。
int i = 8; dynamic d; if (someVar is dynamic) { } d = i as dynamic; Console.WriteLine(typeof(List<dynamic>)); //Console.WriteLine(typeof(dynamic)); //編譯錯誤
5.dynamic與ViewBab
ViewBab是一個dynamic類型的屬性,所以編譯器不會對它進行檢查,所以我們可以自定義屬性。我們也可以通過ExpandoObject() 這個類來實現我們自己的ViewBab,看下麵示例:
public class Program { public static void Main(string[] args) { dynamic model = new ExpandoObject(); //在運行時,model 會轉化為 ExpandoObject() 的一個實例 model.Index = 0; //ExpandoObject() 有一個事件 PropertyChanged,運行時動態觸發這個事件, model.Number = 0; //然後將Index與Number這個兩個屬性添加到類中 Console.WriteLine(model.Index); Console.WriteLine(model.Number); Console.ReadKey(); } }
也許你會覺得dynamic用到的不多,所以不必深入理解,但等到你真正遇到它時,將會吃大虧。正如上面講的那樣,它在COM API 、 動態API 、HTML對象模型的操作上有重要作用,通過它,可以簡化操作,但同時它也容易讓人迷糊(它所指向的究竟是什麼樣的對象類型),因為簡化通常意味著隱藏,它將複雜的後臺實現封裝並開放見簡單的介面給我們使用,這樣簡化了我們的操作,卻然我們更容易迷惑,我們不知道它為什麼要這樣做,只知道可以這樣做,使得我們在很多問題上無法深入挖掘。在網站開發中,深入理解dynamic,有利於我們深入到框架內部去,對我們學習.Net架構是非常有幫助的。
原文鏈接:https://www.cnblogs.com/SilentCode/p/4920598.html