Поделиться через


Критические изменения в Visual Basic 2010

В следующей таблице перечислены все изменения, которые могут заблокировать компиляцию в Visual Basic 2010 для приложения, созданного в Visual Basic 2008, или могут изменить его поведение во время выполнения.

Категория

Проблема

Описание

Определение типа массива

Изменились правила зависимости для инициализаторов массива.

Например, Dim x() = {1, 2, 3} определяется как Integer.

Dim x() = {1, 2.2, "3"} вызывает ошибку компилятора, когда для Option Strict установлено значение On.

Если при объявлении переменной массива в 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.

Лямбда-выражения

Анонимные лямбда-выражения создают уникальные типы.

Типы анонимных делегатов, созданные для лямбда-выражений, стали уникальными. Это может повлиять на код, оценивающий равенство типов анонимных делегатов, например, такой, как в следующем примере.

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())

Дополнительные сведения см. в разделе Лямбда-выражения (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 с помощью оператора = выдается результат False, даже если тип значения, допускающий значение Null, имеет значение Nothing, что отличается от ожидаемого результата. Используйте вместо этого оператор 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 больше не подразумевается.

Visual Basic 2008 вызывает ограничение Class для универсального параметра, если он ограничен вторым универсальным параметром, который ограничен с помощью ограничения 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).

Деревья выражений для лямбда-выражений

Устранение ненужной упаковки экземпляров универсальных типов параметра

Если внутри дерева выражения для лямбда-выражения в Visual Basic 2008 универсальный тип параметра ограничен до интерфейса, то при вызове метода для экземпляра этого типа всегда выполняется упаковка данного экземпляра. В Visual Basic 2010 такой экземпляр упаковывается только при необходимости.

Дополнительные сведения об упаковке и распаковке см. в разделе Спецификация языка Visual Basic.

Лямбда-выражения и деревья выражений

Дерево выражения для лямбда-выражения может быть возвращено из дерева выражения для лямбда-выражения.

Если в Visual Basic 2008 лямбда-выражение приводит лямбда-выражение к дереву выражения, в некоторых случаях компилятор не выполняет приведение. Компилятор Visual Basic 2010 правильно приводит лямбда-выражения как деревья выражений, если приведение выполняется внутри лямбда-выражения.

См. также

Основные понятия

Новые возможности Visual Basic 2010

Другие ресурсы

Приступая к работе с Visual Basic