︿
Top

2016年3月8日 星期二

C#: dynamic, var, object comparing

緣起

日前看到一篇針對 dynamic, var, object 比較的不錯文章 (MSDN Magazine: Understanding the Dynamic Keyword in C# 4), 茲將重點節錄如下, 以防以後忘記.


var

編譯時期決定資料型別

var varExample = 10;
Console.WriteLine(varExample.GetType()); //System.Int32
varExample = varExample + 10;   //this is OK
varExample = "test";    //Compile Failed, 不可隨時轉換資料型別

dynamic

執行時期決定資料型別, 但可一再重複更換; 且 ‘不需’ 強制轉型;
這是在 C# 4.0 新導入的關鍵字.

dynamic dynamicExample = 10;
Console.WriteLine(dynamicExample.GetType()); //System.Int32
dynamicExample = dynamicExample + 10;  //this is OK, 不需轉型
dynamicExample = "test";   //this is OK, 可隨時轉換資料型別

object

執行時期決定資料型別, 但可一再重複更換; 且 ‘必需’ 強制轉型.

object objExample = 10;
Console.WriteLine(objExample.GetType()); //System.Int32
objExample = (int)objExample + 10;  //this is OK, 但必須強制轉型
objExample = "test";    //this is OK, 可隨時轉換資料型別

思考

以下程式段落裡, anotherObject 的類型是什麼? 答案是: dynamic. 因為:
var 關鍵字是一個指令, 而不是資料型別, 它讓編譯器根據變數的初始設定式 (等號右方的資料型別) 推斷類型. 而 dynamicObject 這個變數的型別為 dynamic, 即使當初在初始 dynamicObject 時, 是採用 new Object() 的方式; 故編譯時期看到的是 dynamic, 而執行時期看到的是 Object.

dynamic dynamicObject = new Object();
var anotherObject = dynamicObject;
// anotherObject 
// 編譯時期: dynamic
// 執行時期: System.Object
Console.WriteLine(anotherObject.GetType());  

在將滑鼠移到 anotherObject 變數上, 會出現下圖, 代表是 dynamic



執行結果


dynamic 進階

程式言可以區分為2類:
Static: 在編譯時期進行型別檢查.
    優點: 編譯時期可以找出錯誤, 且可支援 intellisense
    缺點: 與外部程式庫溝通不易 (ex: Offiec Interop, 必須要一堆的型別轉換)
    範例: C#, Java
Dynamic: 不在編譯時期進行型別檢查
    優點: 代碼編寫起來往往更快, 更容易
    缺點: (1) 由於不會獲得編譯器錯誤, 只能通過單元測試和其他方法來確保應用程式正常運行.
              (2) 無法支援 intellisense.  "This problem might be solved with additional type inference, as is done in the IronPython tools for Visual Studio, but for now C# doesn’t provide it. "
    範例: Python, Ruby and JavaScript
    註: 關於 Intellisense 的功能與開發工具的支援有關, 就筆者查證, Visual Studio 2012 起已可支援 JavaScript
 
C# 是靜態的程式語言, 在 C# 4.0 導入了 dynamic 及 DLR (Dynamic Language Runtime), 以改善與其它動態語言或 COM 元件的協同合作.

"When you hear the term “dynamic” in regard to the C# language, it usually refers to one of two concepts: the dynamic keyword in C# 4 or the DLR. Although these two concepts are related, it’s important to understand the difference as well."

"The DLR serves two main goals. First, it enables interoperation between dynamic languages and the .NET Framework. Second, it brings dynamic behavior to C# and Visual Basic."


以下為 C# 有無採用 dynamic 在進行 Excel 文件處理時的差別. 參考自 How to: Access Office Interop Objects by Using Visual C# 2010 Features (C# Programming Guide); 如果會用到 Office 的, 可以參考看看.

由於在參考 Microsoft.Office.Interop.Excel 或 Microsoft.Office.Interop.Word 時, 其預設的 "Embed Interop Types" 屬性為 true; 故預設狀況下, 編譯器會將 Object 視為 dynamic 作處理, 可以簡化一些程式碼 (但無法享有 intellisense 的好處)

// C# 4.0 可以不用作一堆的型別轉換
workSheet.Columns[1].AutoFit();
workSheet.Columns[2].AutoFit();

// 舊版 C# 需要將這些作業明確轉型, 因為 ExcelApp.Columns[1] 傳回 Object; 而 AutoFit() 是 Excel Range 方法. 
((Excel.Range)workSheet.Columns[1]).AutoFit();
((Excel.Range)workSheet.Columns[2]).AutoFit();


總結

var: 編譯時期決定資料型別
dynamic: 執行時期決定資料型別, 但可一再重複更換; 且 ‘不需’ 強制轉型
object: 執行時期決定資料型別, 但可一再重複更換; 且 ‘必需’ 強制轉型

原本沒有打算寫 "dynamic 進階" 這個段落, 但發現不寫又好像少了什麼, 而越寫看的資料也越多, 這也算是收穫吧 ^^

參考文件




沒有留言:

張貼留言