Visual Basic 2010的新增功用。本站提示廣大學習愛好者:(Visual Basic 2010的新增功用)文章只能為提供參考,不一定能成為您想要的結果。以下是Visual Basic 2010的新增功用正文
自 1991 年 Visual Basic 言語降生之日起,它就不斷是生成使用順序的高效 率工具。將近 20 年之後,它持續提供與 Microsoft .NET Framework 的輕松對 接,使開發人員可以編寫可跨越桌面、電話、閱讀器甚至雲的使用順序。
Microsoft 將在本月發布 Visual Studio 2010,其中包括 Visual Basic 版本 10(有時稱為 VB 2010 或 VB10)。此版本是迄今為止最弱小的版本,包括 許多省時省力的功用,可以協助開發人員經過更少的代碼行完成更多的操作。在 這裡,將會為您提供一切必要的內容,讓您充沛理解並應用 Visual Studio 2010 中的 Visual Basic。
共同演化
在過來,Visual Basic 和 C# 是 由獨立團隊辨別開發的,這通常會招致一些功用先呈現在一種言語中,繼而又出 如今另一種言語中。例如,C# 有 Visual Basic 中所沒有的自動完成屬性和集合 初始值設定項,而 Visual Basic 則有 C# 中所沒有的早期綁定和可選參數等功 能。但每當一種言語具有新功用時,許多客戶都會要求將該功用也添加到另一種 言語中。
為理解決這一需求,Microsoft 兼並了 Visual Basic 和 C# 團 隊,實行共同演化的戰略。目的是為推進這些言語共同開展。當一種言語中引入 嚴重功用時,它也會呈現在另一種言語中。這並不是說每種功用都將呈現在兩種 言語中,並按完全相反的方式任務;實踐上,每種言語都有自己的歷史、靈魂和 覺得 – 保存這些特性十分重要。共同演化意味著您在一種言語中可以執行 的任何義務都可以經過另一種言語輕松完成。
在 .NET Framework 4 中, Visual Basic 和 C# 朝這一目的邁進了一大步,辨別吸收了對方既有的許多功用 。但是,共同演化不只影響到以前的功用;它異樣是這些言語將來的開展戰略。 本著這種肉體,.NET Framework 4 在兩種言語中同時引入了弱小的新功用,例如 靜態言語運轉時、嵌入式互操作類型和泛型方差,從而使 Visual Basic 和 C# 開發人員可以充沛應用 .NET Framework。
Visual Basic 2010 新增功用
Visual Basic 2010 中的新功用旨在協助您經過更少的代碼行完成更多操 作。我們 Visual Basic 設計團隊細心研討了開發人員通常不得不編寫少量繁瑣 樣板代碼的中央,並找到相應處理方法,讓編譯器替代執行此類任務。當然,這 是從全體下去看,如今就讓我們深化理解各項功用。
隱式行持續符
Visual Basic 是一種面向行的言語,它運用相似於英語的明晰語法來增 強可讀性。但這通常會招致代碼遇到每行 80 個字符的限制,從而迫使開發人員 要停止少量滾動。您可以運用下劃線字符來告知編譯器應將下一行作為以後行繼 續處置(也就是說,將多個物理行視為單個邏輯行)。但不得不反復地鍵入下劃 線字符不斷很令人懊惱,而現實上多年以來排在首位的功用懇求就是讓編譯器 “處理這個問題”。
而在 Visual Basic 2010 中,編譯器能 夠處理這個問題。編譯器如今知道哪些標志(例如逗號、圓括號和運算符)往往 呈現外行持續符後面,並且它會拔出字符,因而開發人員不再需求拔出字符。例 如,用逗號作為 Visual Basic 語句的開頭一定不合邏輯;編譯器知道這一點, 因而,當編譯器看到諸如 {comma, enter} 這樣的標志流時,它會推斷出存外行 持續符,如圖 1 中的示例所示。
圖 1 推斷出行持續符
<Extension()> Function FilterByCountry( ByVal customers As IEnumerable(Of Customer), ByVal country As String) As IEnumerable(Of Customer) Dim query = From c In customers Where c.Country = country Select <Customer> <%= c.Name & "," & c.Country %> </Customer> Return query End Function
在 Visual Basic 2008 中,圖 1 中的代碼將需求 9 個下劃線字符。但是,在以下每種狀況下,編譯器會推斷出下劃線字符在何時是 必要的,並允許將其疏忽:
在 <Extension()> 屬性之後
在 辦法聲明中的 ((左圓括號)之後
在第一個參數的 ,(逗號)之後
在辦法聲明中的 )(右圓括號)之前
在 =(等號)之後
在 <%=(嵌入式表達式的開端標志)之後
在 XML 文本的每個 &(與號)之後
在 %>(嵌入式表達式 的完畢標志)之前
這個新的編譯器功用關於辦法簽名特別有用,它關於所 示示例中超越 80 個字符的狀況也將正常任務(假如每一局部都位於同一行上) 。在圖 2 中,您將看到行持續符為隱式的標志和地位的一切組合。
圖 2 行持續符為隱式的狀況
標志 之前 之後 ,(逗號)、.(句點)、>(屬性)、( {(左括 號)、<%=(嵌入式表達式開端標志(XML 文本)) X )、}、](右括號)、%>(嵌入式表達式完畢 標志) X 一切 LINQ 關鍵字:
Aggregate、 Distinct、From、Group By、Group Join、Join、Let、 Order By、Select、Skip、Skip While、Take、Take While、Where、In、Into、 On、Ascending、Descending
X X 運算 符:
+、 -、*、/、、^、>>、<<、Mod、&、+=、-=、*= 、/=、=、^=、>>=、<& lt;=、&=、<、<=、>、 >=、<>、Is、IsNot、Like、And、Or、Xor、 AndAlso、 OrElse
X With(在對象初始值設定項中 ) X如您所見,有 60 多處該 言語不需求下劃線字符的中央。(現實上,本文中的任何一個代碼示例都不需求 行持續符。)當然,您依然可以運用下劃線字符,因而 Visual Basic 以前版本 中的代碼將依然按預期方式編譯。
語句 Lambda
術語 lambda 乍聽 上去能夠很嚇人,但 lambda 只是在另一個函數內定義的函數。Visual Basic 2008 引入了帶 Function 關鍵字的 lambda 表達式:
Dim customers As Customer() = ... Array.FindAll(customers, Function(c) c.Country = "Canada")
Lambda 表達式使您可以在本地以細致緊湊的方式表達邏輯,而不用跨 多個辦法拆分邏輯。例如,上面是 Visual Basic 2005(不支持 lambda 表達式 )中以前的代碼的表示方式:
Dim query = Array.FindAll (customers, AddressOf Filter) ... Function Filter(ByVal c As customer) As Boolean Return c.Country = "Canada" End Function
不幸的是,Visual Basic 2008 的 lambda 表達式要求 表達式前往值,因而以下代碼:
Array.ForEach(customers, Function(c) Console.WriteLine(c.Country))
將會招致以下狀況:
'Compile error: "Expression does not produce a value."
Console.WriteLine 是一個 Sub 進程(C# 中為 void),因而 它不會前往值,而這就是編譯器發生錯誤的緣由所在。為了處置此狀況,Visual Basic 2010 引入了對語句 lambda 的支持,後者是包括一個或多個語句的 lambda:
Array.ForEach(customers, Sub(c) Console.WriteLine (c.Country))
由於 Console.WriteLine 不前往值,因而我們可以只創 建 Sub lambda,而不是 Function lambda。上面是運用多個語句的另一個示例:
Array.ForEach(customers, Sub(c) Console.WriteLine("Country Name:") Console.WriteLine(c.Country) End Sub)
當此代碼運轉時,它將為每個 客戶打印兩行。另外請留意,假如在編碼時懸停在 c 上,您將看到編譯器會將類 型推斷為 Customer(鍵入 c As Customer 來顯式聲明類型也是合法的)。靜態 編寫事情處置順序是語句 lambda 的另一個出色用處:
AddHandler b.Click, Sub(sender As Object, e As EventArgs) MsgBox("Button Clicked") 'insert more complex logic here End Sub
並且,現實上,您可以將語句 lambda 與 Visual Basic 2008 中引入的一項功用(松懈委托)結合運用。(可以運用委 托 – 類型平安的函數指針 – 一次性執行多個函數。)這種組合將 生成更為復雜的簽名:
AddHandler b.Click, Sub() MsgBox("Button Clicked") 'insert more complex logic here End Sub
委托松懈使您可以完全疏忽事情處置順序中的參數 – 這是一個很好的 優點,只需它們基本未運用過,因而它們只會在視覺上帶來攪擾。
除了到 目前為止我們已看到的單行 Sub lambda 和多行 Sub lambda 外,Visual Basic 2010 還支持多行 Function lambda:
Dim query = customers.Where(Function(c) 'Return only customers that have not been saved 'insert more complex logic here Return c.ID = -1 End Function)
語句 lambda 的另一個 引人關注的方面是它們與 Visual Basic 2008 引入的匿名委托的相交方式。人們 常常將這些委托與 C# 的匿名辦法混雜,雖然嚴厲來說它們並不相反。當 Visual Basic 編譯器基於 lambda 的辦法簽名推斷委托類型時,將發作匿名委托:
Dim method = Function(product As String) If product = "Paper" Then Return 4.5 'units in stock Else Return 10 '10 of everything else End If End Function MsgBox(method("Paper"))
假如運轉此代碼,您將看到音訊框中顯示值 4.5。此外,假如懸停在 method 上,您將看到文本 Dim method As <Function(String) As Double>。由於我們未提供實踐委托類型,因而編 譯器將自動生成一個委托類型,如下所示:
Delegate Function $compilerGeneratedName$(product As String) As Double
這稱為 匿名委托,由於它只會呈現在編譯器生成的代碼中,而不會呈現在編寫的代碼中 。請留意,當現實上沒有提供 As 子句來指定 lambda 的前往類型時,編譯器將 前往類型推斷為 Double。編譯器將檢查 lambda 內的一切前往語句,並將確定類 型 Double (4.5) 和 Integer (10):
'Notice the "As Single" Dim method = Function(product As String) As Single If product = "Paper" Then Return 4.5 'units in stock Else Return 10 '10 of everything else End If End Function
然後,它將運轉其基准類型算法,並確 定它可以平安地將 10 轉換為 Double,但無法平安地將 4.5 轉換為 Integer; 因而 Double 是更好的選擇。
您也可以顯式控制前往類型,在這種狀況下 ,編譯器將不會嘗試推斷類型。十分罕見的做法是將 lambda 賦給具有顯式委托 類型的變量,而不是依賴於編譯器來推斷委托類型:
Dim method As Func(Of String, Single) = Function(product) If product = "Paper" Then Return 4.5 'units in stock Else Return 10 '10 of everything else End If End Function
由於提供了顯式目的類型,因而無需聲明 As String 或 As Single;編譯器可基於語句右邊的委托類型來推斷出其存在。因而,假如 您懸停在 product 上,將會發現推斷出的類型為 String。不再必需指定 As Single,由於委托類型已提供該信息。在後面的示例中,Func 委托(.NET Framework 包括該委托)的簽名如下所示:
Delegate Function Func(Of T, R)(ByVal param As T) As R
但有一個很小的例外 之處,稍後我們將在“泛型方差”一節中看到。
自動完成的屬 性
在 Visual Basic 中,屬性是用於向內部地下對象形態的類成員。典型 的屬性聲明與如下聲明相似:
Private _Country As String Property Country As String Get Return _Country End Get Set(ByVal value As String) _Country = value End Set End Property
一個實踐上十分復雜的概念就有 10 行代碼。由於典型 的對象通常無數十個屬性,因而您最終會在類定義中包括少量樣板代碼。為了簡 化此類義務,Visual Basic 2010 引入了自動完成的屬性,應用該屬性,您只需 運用一行代碼即可定義復雜的屬性:
Property Country As String
在這種狀況下,編譯器將持續運 行並自動生成 Getter、Setter 和支持字段。支持字段的稱號是一直為後面帶有 下劃線字符的屬性的稱號:此例中為 _Country。這種命名商定在將自動完成的屬 性更改為慣例屬性的狀況下確保了二進制序列化兼容性。只需支持字段的稱號相 同,二進制序列化就將持續任務。
您可運用自動完成的屬性執行的其中一 項出色的功用是:指定在結構函數運轉時設置屬性默許值的初始值設定項。舉例 來說,一個帶有實體類的罕見方案將主鍵設置為相似於 -1 的值,以指示其處於 未保管的形態。代碼將如下所示:
Property ID As Integer = - 1
當結構函數運轉時,支持字段 (_ID) 將自動設置為值 -1。初始值設 定項語法也適用於援用類型:
Property OrderList As List(Of Order) = New List(Of Order)
由於無需輸出兩次類型的稱號,因 此上一行代碼能夠不會具有十分分明的“Visual Basic 特征”。好消 息是,慣例變量聲明中有一個與 Visual Basic 所允許語法分歧的更短的語法:
Property OrderList As New List(Of Order)
您甚至能 夠將此語法與對象初始值設定項結合運用,以允許設置其他屬性:
Property OrderList As New List(Of Order) With {.Capacity = 100}
很顯然,關於更復雜的屬性,擴展的語法依然是 必要的。您依然可以鍵入 Property{Tab} 來激活舊屬性片段。或許,在鍵入屬性 的第一行後,您可以只輸出 Get{Enter},IDE 將生成舊款式的屬性:
Property Name As String Get End Get Set(ByVal value As String) End Set End Property
人們通常會發現:新的屬性語法與公共字段的語法簡直 相反,那麼為什麼不改為運用公共字段?有幾個緣由:
大少數 .NET 數據 綁定根底構造都根據屬性(而不是字段)任務。
接口無法強迫要求存在字 段;但可以強迫要求存在屬性。
屬性為更改業務規則提供了更臨時的靈敏 性。例如,假定某人引入了電話號碼必需為 10 位數的規則。假如分配給公共字 段,將無法執行此驗證。關於諸如二進制序列化和反射等方案而言,將公共字段 更改為屬性是一項嚴重更改。
集合初始值設定項
一種罕見 .NET 做法是實例化集合,然後經過為每個元素調用一次 Add 辦法來填充該集合:
Dim digits As New List(Of Integer) digits.Add(0) digits.Add(1) digits.Add(2) digits.Add(3) digits.Add(4) digits.Add(5) digits.Add(6) digits.Add(7) digits.Add(8) digits.Add(9)
但關於從基本上而言十分復雜的概念來說,將會發生大 量語法開支。Visual Basic 2010 引入了集合初始值設定項,使您可以更輕松地 實例化集合。關於此代碼:
Dim digits = New List(Of Integer) From {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
編譯器將自動生 成對 Add 辦法的一切調用。您也可以運用 Visual Basic 的 As New 語法的功用 :
Dim digits As New List(Of Integer) From {1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
請留意,在 Visual Basic Team 上,我 們不斷建議運用第二種語法 (As New),而不是前者,由於它使代碼更能順應 Option Infer 設置的更改。
您可以根據滿足以下要求的任何類型運用集 合初始值設定項:
您可以運用 For Each 語句循環訪問該類型 – 也就是說,該類型完成 IEnumerable。(有關集合類型更准確/詳細的定義,請參 見 msdn.microsoft.com/library/aa711986(VS.71).aspx 上 Visual Basic 言語 標准的第 10.9.3 節)。
該類型具有可訪問的(但不一定是公共)無參數 結構函數。
該類型具有可訪問的(但不一定是公共)實例或名為 Add 的 擴展辦法。
這意味著,您也可以將集合初始值設定項用於更復雜的類型, 例如字典:
Dim lookupTable As New Dictionary(Of Integer, String) From {{1, "One"}, {2, "Two"}, {3, "Three"}, {4, "Four"}}
(請留意,即便此語句跨了五行,也沒有下劃線字 符。)在這種狀況下,編譯器將生成與初始化字典的舊辦法等效的代碼:
Dim lookupTable As New Dictionary(Of Integer, String) lookupTable.Add(1, "One") lookupTable.Add(2, "Two") lookupTable.Add(3, "Three") lookupTable.Add(4, "Four")
編譯器在調器具有兩個 參數(而不是一 個參數)的 Add 辦法。它之所以知道這樣做,緣由是傳入集合初始值設定項的值 位於嵌套的大括號中,如下所示:{{1, “One”}, {2, “Two”}, …}。關於每一組嵌套的大括號,編譯器會嘗試將這 些參數傳遞到兼容的 Add 辦法。
也可以經過運用擴展辦法來提供您自己 的自定義 Add 完成:
<Extension()> Sub Add(ByVal source As IList(Of Customer), ByVal id As Integer, ByVal name As String, ByVal city As String) source.Add(New Customer With { .ID = id, .Name = name, .City = city }) End Sub
(看看一切這些缺失的下劃線字符!)此辦法擴展任何完成 IList(Of Customer) 的類型,然後允許您運用新的集合初始值設定項語法,如下 所示:
Dim list = New List(Of Customer) From { {1, "Jon", "Redmond"}, {2, "Bob", "Seattle"}, {3, "Sally", "Toronto"} }
(向列表 中添加三個客戶)。您也可以將集合初始值設 定項與自動完成的屬性結合運用:
Property States As New List (Of String) From {"AL", "AK", "AR", "AZ", ...}
數組文本
除了更弱小的集合類型處置方式外,Visual Basic 2010 還提供了一些用 於處置數組的弱小加強功用。假定有以下代碼(在較舊版本中可正常任務):
Dim numbers As Integer() = New Integer() {1, 2, 3, 4, 5}
經過檢查該數組中的元素,很分明每個元素都是整數,因而,必 須實踐上在此行中打印輸入兩次 Integer 的操作不會真正添加任何值。數組文本 允許將某個數組的一切元素放在大括號內,然後讓編譯器自動推斷類型,從而創 建該數組:
Dim numbers = {1, 2, 3, 4, 5}
numbers 的類型不是 Object,而是 Integer()(只需啟用了“Option Infer” ),緣由是數組文本如今可代表自身,並且有其自己的類型。假定有一個更復雜 的示例:
Dim numbers = {1, 2, 3, 4, 5.555}
在這 種狀況下,numbers 的類型將被推斷為 Double()。編譯器經過反省數組中的每個 元素並計算基准類型(所運用的算法與後面討論的用於推斷語句 lambda 的前往 類型的算法相反),從而確定類型。假如沒有基准類型將會發作什麼狀況?例如 ,以下代碼中所示:
Dim numbers = {1, 2, 3, 4, "5"}
在這種狀況下,將 Integer 轉換為 String 將會減少轉換范圍(也就 是說,在運轉時能夠會呈現數據喪失的狀況),異樣,將 String 轉換為 Integer 也會減少轉換范圍。可選擇的獨一平安的類型為 Object()(假如啟用了 “Option Strict”,編譯器將發生錯誤)。
可以嵌套數組文 本以構成多維數組或交織數組:
'2-dimensional array Dim matrix = {{1, 0}, {0, 1}} 'jagged array - the parentheses force evaluation of the inner array first Dim jagged = { ({1, 0}), ({0, 1}) }
靜態言語運轉時
雖然 Visual Basic 從技術上而言本質上是靜態言語,但它不斷有十分強 大的靜態功用,例如早期綁定。Visual Studio 2010 附帶了一個名為靜態言語運 行時 (DLR) 的新平台,應用該平台可更為輕松地生成靜態言語 – 並在這 些言語之間通訊。Visual Basic 2010 已更新為在其早期綁定順序中完全支持 DLR,從而使開發人員可以運用采用其他言語(例如 IronPython/IronRuby)開發 的庫和框架。
此功用的一項突出優點是,從語法上而言沒有任何內容發作更改(現實上,在 編譯器中沒有修正任何一行代碼來支持此功用)。開發人員依然可以像在 Visual Basic 以前的版本中一樣停止早期綁定的操作。發作變化的是 Visual Basic 運 行庫 (Microsoft.VisualBasic.dll) 中的代碼,該運轉庫如今可辨認 DLR 提供 的 IDynamicMetaObjectProvider 接口。假如某個對象完成此接口,則 Visual Basic 運轉庫將構建 DLR CallSite,並允許該對象及提供該對象的言語將它們自 己的語義注入操作。