共用方式為


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 識別項緊接在查詢後面,則由於查詢子句的隱含行接續符號規則,此識別項會被視為查詢的一部分。 在這個範例中,這會造成編譯器錯誤。

Dim aggregate = 0
Dim numbers = {1, 2, 3, 4, 5}
Dim query As IEnumerable(Of Integer)

While aggregate < 5

    query = From i In numbers
            Skip aggregate
            Take 1
            Select i
    aggregate += 1

End While

若要確保一行程式碼不被隱含地納入前一行,請在該行程式碼前面加上額外的分行符號,如以下範例所示。

    query = From i In numbers
            Skip aggregate
            Take 1
            Select i

    aggregate += 1

如需隱含行接續符號的詳細資訊,請參閱 Visual Basic 中的陳述式

模組

模組會編譯為 MustInherit。

模組現在會編譯為 MustInherit。 這並不影響模組的行為方式,但會影響使用反映來檢查 Visual Basic Module 陳述式所建立型別的程式碼。 如需詳細資訊,請參閱 Module 陳述式

Lambda 運算式

匿名 Lambda 運算式會產生唯一的型別。

Lambda 運算式所產生的匿名委派型別現在一定是唯一的。 這會影響到評估匿名委派之型別是否相等的程式碼,例如以下範例中的程式碼。

Dim x = Function(a As Integer) a + 1
Dim y = Function(b As Integer) b + 1

' Returns True in Visual Basic 2008. Returns False in Visual Basic 2010.
Dim t = x.GetType().Equals(y.GetType())

如需詳細資訊,請參閱 Lambda 運算式 (Visual Basic)

泛型介面中的變異數

泛型介面可能會引起模稜兩可的情形。

Visual Basic 2010 支援泛型介面中的變異數 (共變數和反變數)。 如果您實作多個介面,而其中一個介面衍生自另一個介面,則可能會收到模稜兩可介面的警告錯誤。

如需詳細資訊,請參閱 泛型介面中的變異數 (C# 和 Visual Basic)

擴充方法

本機方法優於擴充方法。

如果定義某個擴充方法時使用的名稱和參數,與針對型別所定義之方法的名稱和參數相同,則編譯器會繫結至本機方法,而非擴充方法。 這種行為可以修正 Visual Basic 2008 中的錯誤繫結行為。 如需詳細資訊,請參閱 擴充方法 (Visual Basic)

可為 Null 的實值型別

使用 = 運算子測試可為 Null 實值型別是否等於 Nothing (如以下程式碼所示) 時,會產生編譯器錯誤。

Dim i? As Integer
If i = Nothing Then
  ' ...
End If

如果您使用 = 運算子測試可為 Null 實值型別是否等於 Nothing,則即使可為 Null 的實值型別是 Nothing 結果仍會是 False,而這應該不是預期的結果。 請改用 Is 運算子,如下列範例所示。

Dim i? As Integer
If i Is Nothing Then
  ' ...
End If

隱含無參數函式或屬性的引動過程

如果函式或屬性會傳回可索引值 (例如字串或陣列),則只有當函式或屬性沒有多載時,才能使用縮短的語法,依索引參考傳回值的項目。

請參考下列範例中,會傳回可索引值的無參數函式或屬性。

Class Sample

    Public Function GetValue() As String
        Return "Default Value"
    End Function

End Class

您可以使用縮短的語法,依索引參考傳回值的項目,如下列範例所示。

Dim o As Object = New Sample()
' Returns "D" if no overloads exist for the GetValue function.
Dim val = o.GetValue(0)

Visual Basic 2008 可在晚期繫結呼叫使用此縮短語法,即使函式或屬性具有多載也可以。 在 Visual Basic 2010 中,只有當函式或屬性沒有多載時,才能使用縮短語法,依索引參考傳回值的項目。

Class 條件約束

不再假定 Class 條件約束。

如果某個泛型參數被第二個泛型參數所限制,而後者被 Class 條件約束所限制,則 Visual Basic 2008 會推斷第一個泛型參數有 Class 條件約束。 但 Visual Basic 2010 不再推斷泛型參數會「繼承」Class 條件約束。 因為第一個泛型參數可能會以實作介面 (而非類別) 的型別來執行個體化。 介面可滿足 Class 條件約束。

若要確定將泛型參數限制為類別,請加入 Class 條件約束,如下列範例所示。

    ' The following code causes a compiler error.
    ' Function RefEquals(Of T1 As T2, T2 As Class)(ByVal x As T1, ByVal y As T2) As Boolean
    '     Return y Is x
    ' End Function

    ' The following code is valid in Visual Basic 2010.
    Function RefEquals(Of T1 As {T2, Class}, T2 As Class)(ByVal x As T1, ByVal y As T2) As Boolean
        Return y Is x
    End Function

如需詳細資訊,請參閱 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 運算式轉換成運算式樹狀架構。

請參閱

概念

Visual Basic 2010 的新功能

其他資源

Visual Basic 使用者入門