Новые возможности Visual BasicWhat's new for Visual Basic

В этой статье перечислены названия основных возможностей в каждой версии Visual Basic, а также подробно описаны новые и усовершенствованные возможности в самых поздних версиях этого языка программирования.This topic lists key feature names for each version of Visual Basic, with detailed descriptions of the new and enhanced features in the latest versions of the language.

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

Visual Basic 15.5 / Visual Studio 2017 версии 15.5Visual Basic 15.5 / Visual Studio 2017 Version 15.5
Описание новых функций см. в статье Visual Basic 15.5For new features, see Visual Basic 15.5

Предыдущие версииPrevious versions

Visual Basic 15.3 / Visual Studio 2017 версии 15.3Visual Basic 15.3 / Visual Studio 2017 Version 15.3
Описание новых функций см. в статье Visual Basic 15.3For new features, see Visual Basic 15.3

Visual Basic 2017 / Visual Studio 2017Visual Basic 2017 / Visual Studio 2017
Описание новых функций см. в статье Visual Basic 2017For new features, see Visual Basic 2017

Visual Basic / Visual Studio 2015Visual Basic / Visual Studio 2015
Описание новых функций см. в статье Visual Basic 14For new features, see Visual Basic 14

Visual Basic / Visual Studio 2013Visual Basic / Visual Studio 2013
CTP-версии платформы компиляции .NET (Roslyn)Technology previews of the .NET Compiler Platform (“Roslyn”)

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

Visual Basic, Visual Studio 2010Visual Basic, Visual Studio 2010
Автоматически реализуемые свойства, инициализаторы коллекций, неявное продолжение строки, динамические типы, универсальная ковариантность и контрвариантность, доступ к глобальному пространству именAuto-implemented properties, collection initializers, implicit line continuation, dynamic, generic co/contra variance, global namespace access

Visual Basic / Visual Studio 2008Visual Basic / Visual Studio 2008
Интегрированные запросы языка (LINQ), XML-литералы, определение локального типа, инициализаторы объектов, анонимные типы, методы расширений, определение локального типа var, лямбда-выражения, оператор if, типы значений, допускающие значение NULLLanguage Integrated Query (LINQ), XML literals, local type inference, object initializers, anonymous types, extension methods, local var type inference, lambda expressions, if operator, partial methods, nullable value types

Visual Basic / Visual Studio 2005Visual Basic / Visual Studio 2005
Тип My и вспомогательные типы (доступ к приложению, компьютеру, файловой системе, сети)The My type and helper types (access to app, computer, files system, network)

Visual Basic/Visual Studio .NET 2003Visual Basic / Visual Studio .NET 2003
Операторы поразрядного сдвига, объявление переменных циклаBit-shift operators, loop variable declaration

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

Visual Basic 15.5Visual Basic 15.5

Неконечные именованные аргументыNon-trailing named arguments

В Visual Basic 15.3 и более ранних версиях при включении в вызов метода аргументов по положению и по имени позиционные аргументы должны были предшествовать именованным.In Visual Basic 15.3 and earlier versions, when a method call included arguments both by position and by name, positional arguments had to precede named arguments. Начиная с Visual Basic 15.5, позиционные и именованные аргументы могут появляться в любом порядке при условии, что все аргументы до последнего позиционного аргумента находятся в правильном положении.Starting with Visual Basic 15.5, positional and named arguments can appear in any order as long as all arguments up to the last positional argument are in the correct position. Это особенно полезно, если именованные аргументы используются, чтобы сделать код более удобочитаемым.This is particularly useful when named arguments are used to make code more readable.

Например, следующий вызов метода имеет два позиционных аргумента между именованным аргументом.For example, the following method call has two positional arguments between a named argument. Именованный аргумент показывает, что значение 19 представляет возраст.The named argument makes it clear that the value 19 represents an age.

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

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

Это новое сочетание ключевых слов определяет член, доступный для всех членов содержащего его класса, а также типы, производные от содержащего член класса, но только в том случае, если они присутствуют и в сборке, содержащей член.This new keyword combination defines a member that is accessible by all members in its containing class as well as by types derived from the containing class, but only if they are also found in the containing assembly. Так как структуры нельзя наследовать, Private Protected можно применять только к членам класса.Because structures cannot be inherited, Private Protected can only be applied to the members of a class.

Начальный шестнадцатеричный/двоичный/восьмеричный разделительLeading hex/binary/octal separator

В Visual Basic 2017 поддерживается использование подчеркивания (_) в качестве разделителя цифр.Visual Basic 2017 added support for the underscore character (_) as a digit separator. Начиная с Visual Basic 15.5, в качестве начального разделителя между префиксом и двоичными, шестнадцатеричными или восьмеричными цифрами можно использовать знак подчеркивания.Starting with Visual Basic 15.5, you can use the underscore character as a leading separator between the prefix and hexadecimal, binary, or octal digits. В следующем примере начальный разделитель цифр используется для определения 3 271 948 384 в качестве шестнадцатеричного числа:The following example uses a leading digit separator to define 3,271,948,384 as a hexadecimal number:

Dim number As Integer = &H_C305_F860

Чтобы использовать символ подчеркивания в качестве начального разделителя, нужно добавить в файл проекта Visual Basic (*.vbproj) следующий элемент:To use the underscore character as a leading separator, you must add the following element to your Visual Basic project (*.vbproj) file:

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

Visual Basic 15.3Visual Basic 15.3

Вывод именованного кортежаNamed tuple inference

При присвоении значения элементов кортежа из переменных Visual Basic выводит имя элементов кортежа из соответствующих имен переменных; нет необходимости явно называть элемент кортежа.When you assign the value of tuple elements from variables, Visual Basic infers the name of tuple elements from the corresponding variable names; you do not have to explicitly name a tuple element. В следующем примере вывод используется для создания кортежа с тремя именованными элементами: state, stateName и capital.The following example uses inference to create a tuple with three named elements, state, stateName, and capital.

Dim state = "MI"
Dim stateName = "Michigan"
Dim capital = "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

Дополнительные параметры компилятораAdditional compiler switches

Теперь компилятор командной строки Visual Basic поддерживает параметры -refout и -refonly для управления выводом базовых сборок.The Visual Basic command-line compiler now supports the -refout and -refonly compiler options to control the output of reference assemblies. -refout определяет выходной каталог базовой сборки, а -refonly указывает, что в результате компиляции будет выводиться только базовая сборка.-refout defines the output directory of the reference assembly, and -refonly specifies that only a reference assembly is to be output by compilation.

Visual Basic 2017Visual Basic 2017

КортежиTuples

Кортежи представляют собой облегченную структуру данных, которая обычно используется для получения сразу нескольких значений за один вызов метода.Tuples are a lightweight data structure that most commonly is used to return multiple values from a single method call. Как правило, для получения нескольких значений с помощью одного метода необходимо выполнить одно из следующих действий:Ordinarily, to return multiple values from a method, you have to do one of the following:

  • Определить пользовательский тип (Class или Structure).Define a custom type (a Class or a Structure). Это трудоемкое решение.This is a heavyweight solution.

  • Определить один или несколько параметров ByRef помимо возврата значения из метода.Define one or more ByRef parameters, in addition to returning a value from the method.

Поддержка кортежей в Visual Basic позволяет быстро определить кортеж, при необходимости назначить его значениям семантические имена и быстро извлечь его значения.Visual Basic's support for tuples lets you quickly define a tuple, optionally assign semantic names to its values, and quickly retrieve its values. В следующем примере показан вызов метода TryParse и получение кортежа.The following example wraps a call to the TryParse method and returns a tuple.

Imports System.Globalization

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

После этого можно вызвать метод и обработать возвращенный кортеж в коде следующего вида.You can then call the method and handle the returned tuple with code like the following.

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

Двоичные литералы и разделители разрядовBinary literals and digit separators

Двоичный литерал можно определить с помощью префикса &B или &b.You can define a binary literal by using the prefix &B or &b. Для повышения удобочитаемости в качестве разделителя разрядов можно использовать символ подчеркивания (_).In addition, you can use the underscore character, _, as a digit separator to enhance readability. В следующем примере обе эти функции используют для того, чтобы назначить значение Byte и отобразить его как десятичное, шестнадцатеричное или двоичное число.The following example uses both features to assign a Byte value and to display it as a decimal, hexadecimal, and binary number.

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.For more information, see the "Literal assignments" section of the Byte, Integer, Long, Short, SByte, UInteger, ULong, and UShort data types.

Поддержка значений C#, возвращаемых по ссылкеSupport for C# reference return values

Начиная с версии 7.0 C# поддерживает значения, возвращаемые по ссылке.Starting with C# 7.0, C# supports reference return values. Это значит, что в случае, если вызывающий метод получает значение, возвращаемое по ссылке, он может изменить значение ссылки.That is, when the calling method receives a value returned by reference, it can change the value of the reference. Visual Basic не позволяет создавать методы со значениями, возвращаемыми по ссылке, но разрешает получать и изменять такие значения.Visual Basic does not allow you to author methods with reference return values, but it does allow you to consume and modify the reference return values.

Например, следующий класс Sentence, написанный на языке C#, включает метод FindNext, который выполняет поиск следующего слова в предложении, которое начинается с заданной подстроки.For example, the following Sentence class written in C# includes a FindNext method that finds the next word in a sentence that begins with a specified substring. Строка возвращается как значение, возвращаемое по ссылке, а переменная Boolean, переданная в метод по ссылке, показывает, дал ли поиск какие-то результаты.The string is returned as a reference return value, and a Boolean variable passed by reference to the method indicates whether the search was successful. Это означает, что вызывающий объект может не только читать, но и изменять возвращаемое значение, а внесенные изменения отражаются в классе Sentence.This means that the caller can not only read the returned value; he or she can also modify it, and that modification is reflected in the Sentence class.

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

Проще всего изменить найденное в предложении слово с помощью представленного ниже кода.In its simplest form, you can modify the word found in the sentence by using code like the following. Обратите внимание на то, что при этом значение назначается не методу, а выражению, которое возвращается этим методом и представляет собой значение, возвращаемое по ссылке.Note that you are not assigning a value to the method, but rather to the expression that the method returns, which is the reference return value.

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.

Проблема этого кода состоит в том, что в случае, если совпадений нет, метод возвращает первое слово.A problem with this code, though, is that if a match is not found, the method returns the first word. Поскольку код в этом примере не проверяет значение аргумента Boolean, чтобы определить наличие совпадений, в случае, если совпадений нет, он изменяет первое слово.Since the example does not examine the value of the Boolean argument to determine whether a match is found, it modifies the first word if there is no match. В следующем примере эта проблема решена — если совпадений нет, первое слово заменяется само на себя.The following example corrects this by replacing the first word with itself if there is no match.

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.

Лучше использовать вспомогательный метод, в который значение, возвращаемое по ссылке, передается по ссылке.A better solution is to use a helper method to which the reference return value is passed by reference. Впоследствии вспомогательный метод сможет изменить аргумент, передаваемый ему по ссылке.The helper method can then modify the argument passed to it by reference. Эту задачу решает следующий код.The following example does that.

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.

Дополнительные сведения см. в разделе Значения, возвращаемые по ссылке.For more information, see Reference Return Values.

Visual Basic 14Visual Basic 14

NameofNameof
Можно получить неполное имя строки типа или элемента для использования в сообщении об ошибке, не выполняя жесткого программирования строки.You can get the unqualified string name of a type or member for use in an error message without hard coding a string. Это позволяет сохранить правильный код при рефакторинге.This allows your code to remain correct when refactoring. Эта возможность также полезна для прикрепления связей MVC контроллера model-view-controller и инициирования событий изменения свойств.This feature is also useful for hooking up model-view-controller MVC links and firing property changed events.

Интерполяция строкString interpolation
Для создания строк можно использовать выражения интерполяции строк.You can use string interpolation expressions to construct strings. Интерполированное строковое выражение выглядит как шаблонная строка, которая содержит выражения.An interpolated string expression looks like a template string that contains expressions. Интерполированную строку проще понять с точки зрения аргументов, чем составное форматирование.An interpolated string is easier to understand with respect to arguments than Composite Formatting.

Доступ к членам и индексация с проверкой на значение NULLNull-conditional member access and indexing
Прежде чем осуществлять доступ к элементу (?.) или выполнять операцию с индексом (?[]), можно протестировать значение null в очень простой синтаксической конструкции.You can test for null in a very light syntactic way before performing a member access (?.) or index (?[]) operation. Эти операторы позволяют писать меньше кода для проверок значений null, особенно если речь идет о внедрении в структуры данных.These operators help you write less code to handle null checks, especially for descending into data structures. Если левый операнд или объектная ссылка имеет значение null, операция также возвращает значение null.If the left operand or object reference is null, the operations returns null.

Многострочные строковые литералыMulti-line string literals
Строковые литералы могут содержать последовательности новых строк.String literals can contain newline sequences. Прежний обходной путь, связанный с использованием <xml><![CDATA[...text with newlines...]]></xml>.Value, больше не потребуется.You no longer need the old work around of using <xml><![CDATA[...text with newlines...]]></xml>.Value

КомментарииComments
Комментарии можно поместить после неявных продолжений строк, внутри выражений инициализатора и среди условий выражения LINQ.You can put comments after implicit line continuations, inside initializer expressions, and among LINQ expression terms.

Оптимизированное разрешение полных доменных именSmarter fully-qualified name resolution
Имея код, например Threading.Thread.Sleep(1000), Visual Basic выполняла поиск пространства имен «Потоки», обнаруживала, что это пространство имен было неоднозначным в потоках System.Threading и System.Windows.Threading, и сообщала об ошибке.Given code such as Threading.Thread.Sleep(1000), Visual Basic used to look up the namespace "Threading", discover it was ambiguous between System.Threading and System.Windows.Threading, and then report an error. Теперь Visual Basic рассматривает оба возможных пространства имен одновременно.Visual Basic now considers both possible namespaces together. При отображении списка завершения редактор Visual Studio отображает в нем элементы обоих типов.If you show the completion list, the Visual Studio editor lists members from both types in the completion list.

Литералы даты с годом на первом местеYear-first date literals
Литералы даты могут быть указаны в формате гггг-мм-дд, #2015-03-17 16:10 PM#.You can have date literals in yyyy-mm-dd format, #2015-03-17 16:10 PM#.

Свойства интерфейса ReadonlyReadonly interface properties
С помощью свойства readwrite можно реализовать свойства интерфейса readonly.You can implement readonly interface properties using a readwrite property. Интерфейс гарантирует минимальную функциональность и не препятствует функционированию реализующего класса, который разрешает задавать значения для свойства.The interface guarantees minimum functionality, and it does not stop an implementing class from allowing the property to be set.

TypeOf <выражение> IsNot <тип>TypeOf <expr> IsNot <type>
Для удобства чтения кода TypeOf теперь можно использовать с IsNot.For more readability of your code, you can now use TypeOf with IsNot.

#Disable Warning <ИД> и #Enable Warning <ИД>#Disable Warning <ID> and #Enable Warning <ID>
Можно отключить и включить конкретные предупреждения для областей в исходном файле.You can disable and enable specific warnings for regions within a source file.

Усовершенствования комментариев XML-документацииXML doc comment improvements
При написании комментариев к документу разработчик получает доступ к интеллектуальному редактору и поддержку при сборке, что позволяет проверять названия параметров, грамотно обрабатывать crefs (универсальные типы, операторы и т. д.), выделение цветом и рефакторинг.When writing doc comments, you get smart editor and build support for validating parameter names, proper handling of crefs (generics, operators, etc.), colorizing, and refactoring.

Определения частичных модулей и интерфейсовPartial module and interface definitions
Помимо классов и структур можно также объявлять частичные модули и интерфейсы.In addition to classes and structs, you can declare partial modules and interfaces.

Директивы #Region внутри основной части метода#Region directives inside method bodies
Разделители #Region... #End Region можно поместить в любом месте файла, внутри функций и даже в основной части функции.You can put #Region…#End Region delimiters anywhere in a file, inside functions, and even spanning across function bodies.

Определения переопределений являются неявными перегрузкамиOverrides definitions are implicitly overloads
Если добавить в определение модификатор Overrides, компилятор неявно добавляет Overloads, чтобы в общих случаях можно было вводить меньше кода.If you add the Overrides modifier to a definition, the compiler implicitly adds Overloads so that you can type less code in common cases.

В аргументах атрибутов можно использовать объекты CObjCObj allowed in attributes arguments
Компилятор, используемый для вывода ошибки, связанной с тем, что при использовании в конструкциях атрибутов CObj(...) не являлся константой.The compiler used to give an error that CObj(…) was not a constant when used in attribute constructions.

Объявление и использование неоднозначных методов из разных интерфейсовDeclaring and consuming ambiguous methods from different interfaces
Ранее следующий код выдавал ошибки, которые не позволяли объявить IMock или вызвать GetDetails (если эти значения были объявлены в C#).Previously the following code yielded errors that prevented you from declaring IMock or from calling GetDetails (if these had been declared in 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 можно объявить связи интерфейса, как показано в примере.Now the compiler will use normal overload resolution rules to choose the most appropriate GetDetails to call, and you can declare interface relationships in Visual Basic like those shown in the sample.

См. такжеSee also

Новые возможности Visual Studio 2017What's New in Visual Studio 2017