LINQ自學筆記-打地基-區域型別推斷01

  • 6610
  • 0
  • 2012-11-19

LINQ自學筆記-打地基-區域型別推斷01

因為參加 ITHome 的鐵人賽,所以整理了自己學習 LINQ 時的資料,變成自學筆記系列,歡迎指教。這系列的分享,會以 C# + 我比較熟的 Net 3.5 環境為主。

另外本系列預計至少會切成【打地基】和【語法應用】兩大部分做分享。打地基的部分,講的是 LINQ 的組成元素,這部分幾乎和 LINQ 無關,反而是 C# 2.0、C# 3.0 的一堆語言特性,例如:型別推斷、擴充方法、泛型、委派等等,不過都會把分享的範圍限制在和 LINQ 應用有直接相關功能。

PS. LINQ 自學筆記幾乎所有範例,都可直接複製到 LINQPad 4 上執行。因為它輕巧好用,功能強大,寫範例很方便,請大家自行到以下網址下載最新的 LINQPad:http://www.LINQpad.net/。

--------------本文開始-----------------

區域型別推斷(Local Type Inference)從 VB 的角度講比較有趣,C# 就相對單純。細節之後會提到,現在先看一下「型別推斷」是什麼?

MSDN VB:Visual Basic 編譯器會使用「型別推斷」(Type Inference) 來判斷未使用 As 子句宣告之區域變數的資料型別。 編譯器是根據初始化運算式的型別推斷變數的型別。 這可以讓您宣告變數而不用明確陳述型別。

MSDN C#:可以給予區域變數推斷「型別」var,而非明確型別。 var 關鍵字會指示編譯器從初始化陳述式右側的運算式推斷變數的型別。 推斷的型別可能是內建型別、匿名型別、使用者定義型別,或 .NET Framework 類別程式庫中定義的型別。

PS. 在 C# 中,不使用「區域型別推斷」這個名詞,而是用「隱含型別區域變數(Implicitly Typed Local Variables)」,查詢關鍵字要下對喔!

換言之,在 VB 若定義一個區域變數同時賦予值,就可以省略型別宣告,讓編譯器在編譯時期決定變數的型別。這件事在 C# 也適用,只是把原本寫變數型別的地方改用 var 關鍵字即可。另外,因為編譯時期就會推斷出變數的型別,所以其實還是「強型別」的變數。

接著我們注意一個地方,上述定義文字中,都有特別強調一件事,就是【區域變數】!也就是說,型別推斷只適用於下述三種情況::

1. 區域變數(方法範圍中宣告的變數)。

2. 迴圈控制變數的型別(For、Foreach)。

3. Using 陳述式中,用來建立資源名稱的型別。

在實務上,常常會有一些新手開發人員會試圖把方法參數的型別用 var 來取代,但這是不可以的喔!方法參數並非區域變數。

135808

但有趣的事情發生了,在 VB,方法參數我沒有定義型別,卻可以正常調用:

140144

這也是我一開始說型別推斷從 VB 角度講比較有趣的原因,但現在還是先聚焦在型別推斷的使用上。我們先看下述範例,確定了解如何使用型別推斷功能(注意,LINQPad 預設 Statement 和 Expression 兩種撰寫模式之變數都是「區域變數」):

VB:

 


Dim n = 3 
Dim s = "Hello" 
Dim ary = New Integer() { 0, 1, 2 } 
Dim myList = New List(Of Integer)

n.GetType().Dump() 
s.GetType().Dump() 
ary.GetType().Dump() 
myList.GetType().Dump() 

132558

C#:


var i = 5; 
var s = "Hello"; 
var a = new[] { 0, 1, 2 }; 
var list = new List<int>();

i.GetType().Dump(); 
s.GetType().Dump(); 
a.GetType().Dump(); 
list.GetType().Dump();

132651

補充說明,Dump 這個方法,是 LINQPad 所提供的輸出方法,它有六種多載方法,文章末我會附上此方法六種方法的簽名碼(signature),這裡我們先知道 Dump 方法等同於 Console.WriteLine 即可。

上面 VB 和 C# 的範例,我們可以發現定義區域變數時,都沒有宣告型別,但是最後輸出的型別卻是正確的,而且從 IntelliSense 也可以看到,表示 IDE 在我們撰寫程式時,就已經可以如同強型別一樣,推斷出變數型別,並提供該型別可用的方法、屬性、欄位:

133400

到此,型別推斷這個語法特性其實已經大概講完了,應該也都清楚如何使用,下一篇我們再來談談,VB 使用型別推斷有趣而且要注意的地方,並說明上述 VB 的方法參數不定義型別卻可正確呼叫不會發生錯誤的原因。

-----------------LINQPad Dump 方法的簽名碼-----------------

132844

132858

132908

132910

132913

132922

--------
沒什麼特別的~
不過是一些筆記而已