1. 程式人生 > >MVC 之var與dynamic

MVC 之var與dynamic

指向 UC cau 部分 pro datetime ack opera 內部

如果你用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

MVC 之var與dynamic