C# 匿名對象(匿名類型)、var、動態類型 dynamic

来源:http://www.cnblogs.com/dw039/archive/2017/09/04/7472119.html
-Advertisement-
Play Games

本文是要寫的下篇《C#反射及優化用法》的前奏,不能算是下一篇文章的基礎的基礎吧,有興趣的朋友可以關註一下。 隨著C#的發展,該語言內容不斷豐富,開發變得更加方便快捷,C# 的鋒利盡顯無疑。C# 語言從誕生起就是強類型語言,這一性質到今天不曾改變,我想以後也不會變。既然是強類型語言,那編寫任一程式均要 ...


本文是要寫的下篇《C#反射及優化用法》的前奏,不能算是下一篇文章的基礎的基礎吧,有興趣的朋友可以關註一下。

隨著C#的發展,該語言內容不斷豐富,開發變得更加方便快捷,C# 的鋒利盡顯無疑。C# 語言從誕生起就是強類型語言,這一性質到今天不曾改變,我想以後也不會變。既然是強類型語言,那編寫任一程式均要求滿足下麵的基本條件:

1、變數聲明必須指明其類型

2、變數類型明確後,其類型在Runtime亦不能改變

代碼如下:

    public  class Student
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public string Like { get; set; }
    }
static void Main(string[] args)
{
    int a = 10;
    string s = "abc";
    Student student = new Student();
    //下麵出現編譯錯誤,變數類型在聲明後無法再變更
    s = a;
    student = s;
    a = 10.1f;
}

然而,在實際開發中我們經常面臨如下幾種常見問題:

1、在一個較大的程式程式中,只有一處或很少幾處(不超過3處)需要用到 某個或某些類型(如上 Student),其他地方不再需要這些類型。單獨聲明一個Student類型,所需代碼量,可能超過使用該類型時的代碼量,投入產出比不划算。

2、在一處程式中,只需要某種類型對象的部分屬性或方法參與運算。在這種情況下將該類型對象臨時轉換為程式所需的部分屬性和方法的對象,可使程式更加精簡。

3、其他情況........我暫未留意到......歡迎補充........

上面這些 C# 實際開發中常見問題,在 JavaScript 開發中有著比較好的解決方案,如下:

//在此處js中需要模擬一個學生對象
student = {"name":"張三","age":20,"like":"LOL"};
//在此處js中需要模擬一個老師對象
teacher = {"name":"李老師","like":"沒收學生手機,自己LOL"};
//此處需要將學生student轉換成只有name和age的對象
person = {"name":student.name,"age":student.age};

如果你不熟悉上面的js語法,你可以去百度搜索 “json語法”,告訴你很簡單哦(而且很重要)。

匿名對象(匿名類型)

因此C#在3.0版本中吸收了JavaScript腳本語言的這種語法優點,對C#做了相應升級使其也支持這種語法形式(C#依然是強類型語言)。示例代碼如下:

static void Main(string[] args)
{
     new {Name="張三",Age=20,Like="LOL"};
}

上面的C#代碼 通過new關鍵字告訴編譯器要創建一個對象,該對象具有Name,Age,Like三個屬性,=後為屬性對應的值。如此我們避開了“創建一個對象首先要有該對象類型的約束”,因此在開發過程中對於使用較少的類型我們無需再創建單獨的類了,上面提到的問題1被解決

現在創建出來的對象沒指定具體類型,因此稱為匿名對象

Var登場

現在要使用匿名對象,則需要使用變數引用它。雖然我們在創建時沒有指定對象的類型,但編譯器會在編譯過程中幫我們創建一個具有相關屬性和方法的類型。此時編譯出的類型名稱是隨機生成的,因此變數類型無法確定。示例如下:

static void Main(string[] args)
{
    //XXX為類型聲明
    //x為引用變數 
     XXX x = new {Name="張三",Age=20,Like="LOL"};
}

雖然我們不知道編譯器生成的類型名稱,但我們可 讓編譯器自己根據編譯的結果來推斷變數類型。此時var關鍵字便發揮作用了:

 

static void Main(string[] args)
{
     var x = new {Name="張三",Age=20,Like="LOL"};
}

var 關鍵字說明 x 的類型由賦於的值來決定(推定),並能根據編譯器推定給出智能提示,如下圖:

var使用註意事項:

1、var 僅能聲明方法內的局部變數

2、var 聲明的變數在被賦值後類型即確定下了,後續程式中不能在賦其他類型的值

3、var x = new object() 沒有意義,不要寫這樣的代碼...............

 現在有匿名對象和var推斷類型的支持,我們就能處理上面提到的問題2。示例代碼如下:

        static void Main(string[] args)
        {
            var x = new { Name = "張三", Age = 20, Like = "LOL" };
            var s = new { Name = x.Name, Age = x.Age };  
        }

上面僅為示例,如果你熟悉Linq或Entity Framework,那問題2對應的用法將是鋪天蓋地的.......

動態類型 dynamic 出場

對於匿名類型的使用一般局限於方法的局部,可理解為:隨用隨定義,用完就消失。有如下情況應該怎麼辦?

        static void Main(string[] args)
        {
            var x = GetObject(); 
        }

        private static XXX GetObject()
        {
            return new { Name = "張三", Age = 20, Like = "LOL" };
        }

通過GetObject方法返回一個匿名對象,所以方法返回值 類型名稱無法確定,此處暫時用XXX代替。在這種情況下返回的類型不確定,可以使用 dynamic 來指明。如下:

        static void Main(string[] args)
        {
            var x = GetObject(); 
Console.WriteLine(x.Name); }
private static dynamic GetObject() { return new { Name = "張三", Age = 20, Like = "LOL" }; }

此時方法不會出現語法錯誤,程式可以成功編譯並執行。那麼 dynamic 到底做了什麼,可以使上面的程式成功編譯呢?

dynamic的作用:

1、dynamic 表示動態類型,動態類型的含義就是 程式編寫、編譯階段 類型不確定,在Runtime時再通過反射機制確定相關對象的屬性或方法。因此編寫階段不會進行語法檢測。

2、dynamic 可用來聲明 欄位、屬性、方法參數、方法返回值

3、dynamic 不支持智能提示,因為你寫代碼時 dynamic  是什麼沒法知曉(反射)

dynamic 聲明的變數,可理解為 object 類型變數。所以給dynamic變數賦任何類型值都正確,但在使用變數來取得某個屬性值或調用某方法時(此時程式肯定處於Runtime狀態),CLR會檢查(反射)所調用的屬性或方法是否存在,不存在報運行時異常。

dynamic在 Asp.net Mvc web開發中處處使用,雖然看上去很複雜,本質就上面所說內容。

說明:

var 和 dynamic 看似功能類似,但它們是不同的:

  var dynamic
 聲明欄位  ×  √
 局部變數  √  √
 方法參數類型  ×  √
 方法返回值類型  ×  √

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 虛擬簡訊 ...
  • 內容提供者 參考: Android四大組件之內容提供者--ContentProvider - java小兵 - CSDN博客http://blog.csdn.net/wodewutai17quiet/article/details/46670597 Android四大組件之內容提供者--Conten ...
  • 在Android開發中難免會遇到大量的數據載入到ListView中進行顯示, 然後其中最重要的數據傳遞橋梁Adapter適配器是常用的,隨著市場的需 求變化ListView'條目中的內容是越來越多這就需要程式員來自定義適配器, 而關鍵的就是適配器的優化問題,適配器沒有優化好往往就會造成OOM (記憶體 ...
  • 本文主要介紹json最原始的解析與google提供的gson工具類解析 ①json解析 ②gson解析 1)首先在AndroidStudio中安裝一個GsonFormat插件 2)新建一個javaben類然後按下組合鍵alt+insert 把完整的json數據拷貝到編輯框中 3)添加gson的依賴包 ...
  • Android的版本有很多通常開發的時候對話框大多數使用自定義或是 Google提供的V4, V7 相容包來開發保持各個版本的對話框樣式統一,所以這裡使用的是V7 包里的AlertDialog。 ...
  • 中文翻譯文檔: http://blog.csdn.net/rickiyeat/article/details/56483577 版本說明: Jquery v2.1.1 Bootstrap V3.3.7 bootstrap-table V1.11.1 一、視圖頁 1 <!DOCTYPE html> 2 ...
  • C#中Cookies的讀取 鏈接: 一 、寫入Cookie 1. Name 和 Value 屬性由程式設定,預設值都是空引用。 2. Domain屬性的預設值為當前URL的功能變數名稱部分,不管發出這個cookie的頁面在哪個目錄下的。 例如, http://www.kent.com/application ...
  • Cookie客戶端緩存。 1、引言 隨著瀏覽器的處理能力不斷增強,越來越多的網站開始考慮將數據存儲在「客戶端」,那麼久不得不談本地存儲了。 本地存儲的好處: 一是避免取回數據前頁面一片空白,如果不需要最新數據也可以減少向伺服器的請求次數,從而減少用戶等待從服務端獲取數據的時間。 二是網路狀態不佳時仍 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...