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


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

В этой статье перечислены ключевые имена функций для каждой версии Visual Basic. Подробные описания новых и расширенных функций в последних версиях языка см. в связанных разделах.

Текущая версия

Visual Basic 17.13 / Visual Studio 2026
Сведения о новых возможностях см. в Visual Basic 17.13.

Скачать последний пакет SDK для .NET можно на странице загрузки .NET.

предыдущих версий

Visual Basic 17.0 / Visual Studio 2022
Сведения о новых возможностях см. в Visual Basic 17.0.

Visual Basic 16.9 / Visual Studio 2019 версии 16.9
Сведения о новых возможностях см. в Visual Basic 16.9.

Visual Basic 16.0 / Visual Studio 2019 версии 16.0
Сведения о новых возможностях см. в visual Basic 16.0.

Visual Basic 15.5 / Visual Studio 2017 версии 15.5
Сведения о новых возможностях см. в visual Basic 15.5.

Visual Basic 15.3 / Visual Studio 2017 версии 15.3
Сведения о новых возможностях см. в visual Basic 15.3.

Visual Basic 15 / Visual Studio 2017
Сведения о новых возможностях см. в Visual Basic 2017.

Visual Basic / Visual Studio 2015
Сведения о новых возможностях см. в Visual Basic 14.

Visual Basic / Visual Studio 2013
Предварительные версии технологий платформы компилятора .NET (Roslyn)

Visual Basic / Visual Studio 2012
Async и await ключевые слова, итераторы, атрибуты сведений о вызывающем объекте

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

Visual Basic / Visual Studio 2008
Языковой интегрированный запрос (LINQ), XML-литералы, вывод локальных типов, инициализаторы объектов, анонимные типы, методы расширения, вывод локальных var типов, лямбда-выражения, if оператор, частичные методы, типы значений, допускающие значение NULL

Visual Basic / Visual Studio 2005
Тип и вспомогательные My типы (доступ к приложению, компьютеру, файловой системе, сети)

Visual Basic / Visual Studio .NET 2003
Операторы bit-shift, объявление переменной цикла

Visual Basic / Visual Studio .NET 2002
Первый выпуск Visual Basic .NET

Visual Basic 17.13

Visual Basic 17.13 распознает универсальное unmanaged ограничение. Visual Basic 17.13 распознает System.Runtime.CompilerServices.OverloadResolutionPriorityAttribute разрешение методов.

Visual Basic 17.0

Visual Basic 17.0 включает System.Runtime.CompilerServices.CallerArgumentExpressionAttribute.

Visual Basic 16.9

Visual Basic 16.9 позволяет использовать свойства только для инициализации.

Visual Basic 16.0

Visual Basic 16.0 фокусируется на предоставлении дополнительных возможностей среды выполнения Visual Basic (microsoft.visualbasic.dll) в .NET Core. Это первая версия Visual Basic, ориентированная на .NET Core. .NET Core 3.0 добавляет части среды выполнения Visual Basic, зависящие от Windows Forms.

Комментарии, разрешенные в дополнительных местах в инструкциях

В Visual Basic 15.5 и более ранних версиях можно добавлять только комментарии в пустых строках, в конце инструкции или в определенных местах в операторе, где допускается неявное продолжение строки. Начиная с Visual Basic 16.0, вы также можете добавлять комментарии после явных продолжений строк и в инструкции в строке, которая начинается с пробела, за которым следует подчеркивание.

Public Sub Main()
    cmd.CommandText = ' Comment is allowed here without _
        "SELECT * FROM Titles JOIN Publishers " _ ' This is a comment
        & "ON Publishers.PubId = Titles.PubID " _
 _ ' This is a comment on a line without code
        & "WHERE Publishers.State = 'CA'"
End Sub

Оптимизированное преобразование с плавающей запятой на целочисленное

В предыдущих версиях Visual Basic преобразование значений Double и Single в целые числа предложило относительно низкую производительность. Visual Basic 16.0 значительно увеличивает производительность преобразований чисел с плавающей запятой в целые числа, когда значение, возвращаемое любым из следующих методов, передается в одну из встроенных функций преобразования целых чисел Visual Basic (CByte, CShort, CInt, CLng, CSByte, CUShort, CUInt и CULng) или когда значение, возвращаемое любым из следующих методов, неявно приводится к целому типу, и параметр Strict имеет значение Off.

Эта оптимизация позволяет выполнять код быстрее — до двух раз быстрее для кода, выполняющего большое количество преобразований в целые типы. В следующем примере показаны некоторые простые вызовы метода, влияющие на оптимизацию:

Dim s As Single = 173.7619
Dim d As Double = s

Dim i1 As Integer = CInt(Fix(s))               ' Result: 173
Dim b1 As Byte = CByte(Int(d))                 ' Result: 173
Dim s1 AS Short = CShort(Math.Truncate(s))     ' Result: 173
Dim i2 As Integer = CInt(Math.Ceiling(d))      ' Result: 174
Dim i3 As Integer = CInt(Math.Round(s))        ' Result: 174

Эта оптимизация усекает значения с плавающей запятой, а не округляет их.

Visual Basic 15.5

Неконечные именованные аргументы

В Visual Basic 15.3 и более ранних версиях, когда вызов метода включал аргументы как по позиции, так и по имени, необходимо было поместить позиционные аргументы перед именованными аргументами. Начиная с Visual Basic 15.5, вы можете смешивать позиционные и именованные аргументы в любом порядке, пока все аргументы до последнего позиционного аргумента находятся в правильной позиции. Эта гибкость особенно полезна, если именованные аргументы делают код более читаемым.

Например, следующий вызов метода имеет два позиционных аргумента между именованным аргументом. Именованный аргумент дает понять, что значение 19 представляет возраст.

StudentInfo.Display("Mary", age:=19, #9/21/1998#)

Private Protected Модификатор доступа к члену

Это новое сочетание ключевых слов определяет элемент, к которому могут обращаться все члены в его содержающем классе, а также типы, производные от содержащего класса, но только если они также найдены в содержащей сборке. Поскольку структуры не могут наследоваться, можно применять Private Protected только к членам класса.

Ведущий разделитель шестнадцатеричного/двоичного/восьмеричного

Visual Basic 2017 добавил поддержку символа подчеркивания (_) в качестве разделителя цифр. Начиная с Visual Basic 15.5, можно использовать символ подчеркивания в качестве ведущего разделителя между префиксом и шестнадцатеричными, двоичными или восьмеричных цифрами. В следующем примере для определения шестнадцатеричного числа используется разделитель начальной цифры 3 271 948 384:

Dim number As Integer = &H_C305_F860

Чтобы использовать символ подчеркивания в качестве ведущего разделителя, необходимо добавить следующий элемент в файл проекта Visual Basic (*.vbproj):

<PropertyGroup>
  <LangVersion>15.5</LangVersion>
</PropertyGroup>

Visual Basic 15.3

Вывод именованных кортежей

При назначении значения элементов кортежа из переменных Visual Basic выводит имя элементов кортежа из соответствующих имен переменных. Нет необходимости уточнённо называть элемент кортежа. В следующем примере используется вывод для создания кортежа с двумя именованными элементами: state и stateName.

Const state As String = "MI"
Const stateName As String = "Michigan"
Const capital As String = "Lansing"
Dim stateInfo = (state, stateName, capital)
Console.WriteLine($"{stateInfo.stateName}: 2-letter code: {stateInfo.State}, Capital {stateInfo.capital}")
' The example displays the following output:
'      Michigan: 2-letter code: MI, Capital Lansing

Дополнительные коммутаторы компилятора

Компилятор командной строки Visual Basic теперь поддерживает параметры компилятора -refout и -refonly для управления выходными данными ссылочных сборок. Используйте -refout для определения выходного каталога эталонной сборки. Используйте -refonly , чтобы указать, что компиляция выводит только эталонную сборку.

Visual Basic 15

Кортежей

Кортежи — это упрощенная структура данных, которая чаще всего используется для возврата нескольких значений из одного вызова метода. Обычно для возврата нескольких значений из метода необходимо выполнить один из следующих вариантов:

  • Определение пользовательского типа (a Class или a Structure). Этот вариант является тяжеловесным решением.

  • Определите один или несколько ByRef параметров, помимо возврата значения из метода.

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

Imports System.Globalization

Public Module NumericLibrary
    Public Function ParseInteger(value As String) As (Success As Boolean, Number As Integer)
        Dim number As Integer
        Return (Integer.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, number), number)
    End Function
End Module

Затем можно вызвать метод и обработать возвращенный кортеж, как показано в примере кода ниже.

Dim numericString As String = "123,456"
Dim result = ParseInteger(numericString)
Console.WriteLine($"{If(result.Success, $"Success: {result.Number:N0}", "Failure")}")
Console.ReadLine()
'      Output: Success: 123,456

Двоичные литералы и разделители цифр

Двоичный литерал можно определить с помощью префикса &B или &b. Кроме того, можно использовать символ подчеркивания, _как разделитель цифр для повышения удобочитаемости. В следующем примере используются обе функции для назначения Byte значения и отображения его в виде десятичного, шестнадцатеричного и двоичного числа.

Dim value As Byte = &B0110_1110
Console.WriteLine($"{NameOf(value)}  = {value} (hex: 0x{value:X2}) " +
                  $"(binary: {Convert.ToString(value, 2)})")
' The example displays the following output:
'      value  = 110 (hex: 0x6E) (binary: 1101110)      

Дополнительные сведения см. в разделе "Литеральные назначения" типов данных Byte, Integer, Long, Short, SByte, UInteger, ULong и UShort .

Поддержка возвращаемых значений ссылок на C#

C# поддерживает ссылочные возвращаемые значения. То есть, когда вызывающий метод получает значение, возвращаемое ссылкой, оно может изменить значение ссылки. Visual Basic не позволяет создавать методы с возвращаемыми значениями ссылочного типа, но позволяет использовать и изменять возвращаемые значения ссылочного типа.

Например, следующий Sentence класс, написанный на языке C#, включает FindNext метод, который находит следующее слово в предложении, которое начинается с указанной подстроки. Строка возвращается в качестве возвращаемого значения ссылки, а Boolean переменная, передаваемая ссылкой на метод, указывает, успешно ли выполнен поиск. Это означает, что помимо чтения возвращаемого значения вызывающий объект также может изменить его, и это изменение отражается в Sentence классе.

using System;

public class Sentence
{
    private string[] words;
    private int currentSearchPointer;

    public Sentence(string sentence)
    {
        words = sentence.Split(' ');
        currentSearchPointer = -1;
    }

    public ref string FindNext(string startWithString, ref bool found)
    {
        for (int count = currentSearchPointer + 1; count < words.Length; count++)
        {
            if (words[count].StartsWith(startWithString))
            {
                currentSearchPointer = count;
                found = true;
                return ref words[currentSearchPointer];
            }
        }
        currentSearchPointer = -1;
        found = false;
        return ref words[0];
    }

    public string GetSentence()
    {
        string stringToReturn = null;
        foreach (var word in words)
            stringToReturn += $"{word} ";

        return stringToReturn.Trim();
    }
}

В самой простой форме можно изменить слово, найденное в предложении, с помощью кода, как показано в следующем примере. Обратите внимание, что вы назначаете значение не самому методу, а выражению, которое метод возвращает, то есть возвращаемому ссылочному значению.

Dim sentence As New Sentence("A time to see the world is now.")
Dim found = False
sentence.FindNext("A", found) = "A good" 
Console.WriteLine(sentence.GetSentence()) 
' The example displays the following output:
'      A good time to see the world is now.

Проблема с этим кодом, однако, заключается в том, что если совпадение не найдено, метод возвращает первое слово. Так как в примере не проверяется значение аргумента Boolean , чтобы определить, найден ли совпадение, оно изменяет первое слово, если совпадения нет. Следующий пример исправляет эту проблему, заменив первое слово самим собой, если совпадения нет.

Dim sentence As New Sentence("A time to see the world is now.")
Dim found = False
sentence.FindNext("A", found) = IIf(found, "A good", sentence.FindNext("B", found)) 
Console.WriteLine(sentence.GetSentence()) 
' The example displays the following output:
'      A good time to see the world is now.

Лучшее решение — использовать вспомогательный метод, в который передается возвращаемое значение ссылки по ссылке. Вспомогательный метод может изменить аргумент, переданный ему по ссылке. В следующем примере это делается.

Module Example
   Public Sub Main()
      Dim sentence As New Sentence("A time to see the world is now.")
      Dim found = False
      Dim returns = RefHelper(sentence.FindNext("A", found), "A good", found) 
      Console.WriteLine(sentence.GetSentence()) 
   End Sub
   
   Private Function RefHelper(ByRef stringFound As String, replacement As String, success As Boolean) _ 
                    As (originalString As String, found As Boolean) 
      Dim originalString = stringFound
      If found Then stringFound = replacement
      Return (originalString, found)   
   End Function
End Module
' The example displays the following output:
'      A good time to see the world is now.

Дополнительные сведения см. в разделе "Возвращаемые значения ссылок".

Visual Basic 14

NameOf

Для использования в сообщении об ошибке можно получить неквалифицированное строковое имя типа или члена без жесткого написания строки. Этот подход обеспечивает правильность кода при рефакторинге. Эта функция также полезна для подключения связей MVC-контроллера модели и изменения свойств.

Интерполяция строк

Используйте выражения интерполяции строк для создания строк. Интерполированное строковое выражение выглядит как строка шаблона, содержащая выражения. Интерполированная строка проще понять в отношении аргументов, чем составное форматирование.

Доступ и индексирование с условным значением NULL

Перед выполнением операции доступа к члену (?.) или индекса (?[]) можно проверить значение NULL в очень легком синтаксическом способе. Эти операторы помогают создавать меньше кода для обработки проверок NULL, особенно для убывания в структуры данных. Если левая операнда или ссылка на объект имеет значение NULL, операции возвращают значение NULL.

Многострочный строковый литерал

Строковые литералы могут содержать новые строки последовательностей. Вам больше не нужен старый обходной путь использования <xml><![CDATA[...text with newlines...]]></xml>.Value.

Comments

Вы можете поместить комментарии после неявных продолжений строк, внутри выражений инициализатора и среди терминов выражения LINQ.

Интеллектуальное полное разрешение имен

Данный код, как например Threading.Thread.Sleep(1000), программа Visual Basic раньше использовала для проверки пространства имен "Threading", обнаруживала, что он неоднозначен между System.Threading и System.Windows.Threading, и затем сообщала об ошибке. Visual Basic теперь рассматривает оба возможных пространства имен вместе. Если отобразить список завершения, редактор Visual Studio перечисляет членов из обоих типов в списке завершения.

Литералы даты первого года

Можно использовать литералы даты в формате #2015-03-17 16:10 PM#гггг-mm-dd.

Свойства интерфейса readonly

Свойства интерфейса чтения можно реализовать с помощью свойства readwrite. Интерфейс гарантирует минимальный функционал, и не мешает реализующему классу разрешать установку свойства.

Тип TypeOf <expr> IsNot <>

Для повышения удобочитаемости кода теперь можно использовать TypeOfIsNot.

идентификатор предупреждения #Disable и идентификатор< предупреждения ><#Enable>

Вы можете отключить и включить определенные предупреждения для регионов в исходном файле.

Улучшения комментариев xml-документов

При написании комментариев в документации вы получаете поддержку умного редактора и функций сборки для проверки имен параметров, корректной обработки тегов (например, универсальных шаблонов и операторов), подсветки синтаксиса и рефакторинга.

Определения частичного модуля и интерфейса

Помимо классов и структур, можно объявить частичные модули и интерфейсы.

директивы #Region внутри тел метода

Вы можете поместить #Region...#End разделители региона в любое место в файле, внутри функций и даже охватывать органы функций.

Переопределения определений являются неявными перегрузками

При добавлении Overrides модификатора в определение компилятор неявно добавляется Overloads , чтобы можно было вводить меньше кода в распространенных случаях.

CObj разрешен в аргументах атрибутов

Теперь можно использовать CObj(...) в аргументах атрибутов. Ранее компилятор вернул ошибку, заявив, что она не является константой.

Объявление и использование неоднозначных методов из разных интерфейсов

Ранее следующий код возвращал ошибки, которые не позволяло объявить IMock или вызывать GetDetails (если эти методы были объявлены в C#).

Interface ICustomer
  Sub GetDetails(x As Integer)
End Interface

Interface ITime
  Sub GetDetails(x As String)
End Interface

Interface IMock : Inherits ICustomer, ITime
  Overloads Sub GetDetails(x As Char)
End Interface

Interface IMock2 : Inherits ICustomer, ITime
End Interface

Теперь компилятор использует обычные правила разрешения перегрузки, чтобы выбрать наиболее подходящий GetDetails метод для вызова. Вы можете объявить связи интерфейса в Visual Basic, как показано в примере.

См. также