Visual Basic 2010 的重大變更
下列表格列出可能造成在 Visual Basic 2008 中建立的應用程式,無法在 Visual Basic 2010 中進行編譯,或導致執行階段行為改變的變更。
分類 |
問題 |
說明 |
---|---|---|
陣列型別推斷 |
陣列初始設定式的推斷規則已變更。 例如,Dim x() = {1, 2, 3} 會推斷為型別 Integer。 Option Strict 設定為 On 時,Dim x() = {1, 2.2, "3"} 會造成編譯器錯誤。 |
在 Visual Basic 2008 中,宣告陣列變數但省略項目型別時,編譯器會假設項目型別為 Object。 Visual Basic 2010 新增了陣列項目型別推斷,會將項目型別推斷為陣列常值的主型別。 如果沒有主型別,則會假設為 Object 型別。 在這種情況下,如果 Option Strict 設為 On,就會發生編譯器錯誤。 如需詳細資訊,請參閱 Visual Basic 中的陣列。 |
命名衝突 |
對於在檔案層級匯入的命名空間中型別,其優先順序高於在專案層級匯入的命名空間中型別。 |
如果兩個命名空間各自包含一個名稱相同的型別,其中一個型別位於在專案層級匯入的命名空間,另一個相同名稱的型別位於在檔案層級匯入的命名空間,則 Visual Basic 2010 會繫結至在檔案層級匯入之命名空間中的型別; 舊版則是繫結至在專案層級匯入之命名空間中的型別。 如需詳細資訊,請參閱 Imports 陳述式 (.NET 命名空間和型別)。 |
將查詢關鍵字當做識別項 |
將查詢關鍵字當做識別項使用,可能會產生未預期的結果。 |
Visual Basic 編譯器可在各種內容中接受關鍵字做為識別項名稱。 由於 Visual Basic 2010 新增的隱含行接續符號規則,如果您在省略行接續字元的 LINQ 查詢中使用關鍵字做為項目名稱,可能會遇到錯誤。 例如,下列範例使用 Aggregate 關鍵字做為識別項名稱。 如果 aggregate 識別項緊接在查詢後面,則由於查詢子句的隱含行接續符號規則,此識別項會被視為查詢的一部分。 在這個範例中,這會造成編譯器錯誤。
若要確保一行程式碼不被隱含地納入前一行,請在該行程式碼前面加上額外的分行符號,如以下範例所示。
如需隱含行接續符號的詳細資訊,請參閱 Visual Basic 中的陳述式。 |
模組 |
模組會編譯為 MustInherit。 |
模組現在會編譯為 MustInherit。 這並不影響模組的行為方式,但會影響使用反映來檢查 Visual Basic Module 陳述式所建立型別的程式碼。 如需詳細資訊,請參閱 Module 陳述式。 |
Lambda 運算式 |
匿名 Lambda 運算式會產生唯一的型別。 |
Lambda 運算式所產生的匿名委派型別現在一定是唯一的。 這會影響到評估匿名委派之型別是否相等的程式碼,例如以下範例中的程式碼。
如需詳細資訊,請參閱 Lambda 運算式 (Visual Basic)。 |
泛型介面中的變異數 |
泛型介面可能會引起模稜兩可的情形。 |
Visual Basic 2010 支援泛型介面中的變異數 (共變數和反變數)。 如果您實作多個介面,而其中一個介面衍生自另一個介面,則可能會收到模稜兩可介面的警告錯誤。 如需詳細資訊,請參閱 泛型介面中的變異數 (C# 和 Visual Basic)。 |
擴充方法 |
本機方法優於擴充方法。 |
如果定義某個擴充方法時使用的名稱和參數,與針對型別所定義之方法的名稱和參數相同,則編譯器會繫結至本機方法,而非擴充方法。 這種行為可以修正 Visual Basic 2008 中的錯誤繫結行為。 如需詳細資訊,請參閱 擴充方法 (Visual Basic)。 |
可為 Null 的實值型別 |
使用 = 運算子測試可為 Null 實值型別是否等於 Nothing (如以下程式碼所示) 時,會產生編譯器錯誤。
|
如果您使用 = 運算子測試可為 Null 實值型別是否等於 Nothing,則即使可為 Null 的實值型別是 Nothing 結果仍會是 False,而這應該不是預期的結果。 請改用 Is 運算子,如下列範例所示。
|
隱含無參數函式或屬性的引動過程 |
如果函式或屬性會傳回可索引值 (例如字串或陣列),則只有當函式或屬性沒有多載時,才能使用縮短的語法,依索引參考傳回值的項目。 |
請參考下列範例中,會傳回可索引值的無參數函式或屬性。
您可以使用縮短的語法,依索引參考傳回值的項目,如下列範例所示。
Visual Basic 2008 可在晚期繫結呼叫使用此縮短語法,即使函式或屬性具有多載也可以。 在 Visual Basic 2010 中,只有當函式或屬性沒有多載時,才能使用縮短語法,依索引參考傳回值的項目。 |
Class 條件約束 |
不再假定 Class 條件約束。 |
如果某個泛型參數被第二個泛型參數所限制,而後者被 Class 條件約束所限制,則 Visual Basic 2008 會推斷第一個泛型參數有 Class 條件約束。 但 Visual Basic 2010 不再推斷泛型參數會「繼承」Class 條件約束。 因為第一個泛型參數可能會以實作介面 (而非類別) 的型別來執行個體化。 介面可滿足 Class 條件約束。 若要確定將泛型參數限制為類別,請加入 Class 條件約束,如下列範例所示。
如需詳細資訊,請參閱 Visual Basic 中的泛型型別 (Visual Basic)。 |
部分類別方法 |
如果在一個以上的部分類別中宣告具有受限制泛型參數的方法,則所有該方法的宣告都必須有相同的條件約束。 |
您可以在一個以上的部分類別中,宣告具有泛型參數的方法。 在 Visual Basic 2008 中,編譯器並不要求泛型參數上的條件約束必須符合所有該方法的宣告; 但 Visual Basic 2010 就要求該方法的所有宣告都有相同的條件約束。 如需詳細資訊,請參閱 Visual Basic 中的泛型型別 (Visual Basic)。 |
Lambda 運算式的運算式樹狀架構 |
移除不必要的泛型參數型別之執行個體 Boxing |
在 Visual Basic 2008 之 Lambda 運算式的運算式樹狀架構內,如果泛型參數的型別被限制為介面,則在該型別的執行個體上叫用方法時,一律對該執行個體進行 Box 處理; 但在 Visual Basic 2010 中,只有必要時才會對執行個體進行 Box 處理。 如需 Boxing 和 Unboxing 的詳細資訊,請參閱 Visual Basic 語言規格。 |
Lambda 運算式和運算式樹狀架構 |
可以從 Lambda 運算式的運算式樹狀架構傳回 Lambda 運算式的運算式樹狀架構。 |
在 Visual Basic 2008 中,如果 Lambda 運算式將 Lambda 運算式轉換成運算式樹狀架構,編譯器有時候不會執行轉換; 如果轉換發生在 Lambda 運算式中,Visual Basic 2010 編譯器可以正確地將 Lambda 運算式轉換成運算式樹狀架構。 |