Novità in Visual BasicWhat's new for Visual Basic

Questo argomento elenca i nomi delle funzionalità principali per ogni versione di Visual Basic, con descrizioni dettagliate delle funzionalità nuove e migliorate nelle più recenti versioni del linguaggio.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.

Versione correnteCurrent version

Visual Basic 15.8 / Visual Studio 2017 versione 15.8 - Per le nuove funzionalità, vedere Visual Basic 15.8Visual Basic 15.8 / Visual Studio 2017 Version 15.8 For new features, see Visual Basic 15.8

Versioni precedentiPrevious versions

Visual Basic 15.5 / Visual Studio 2017 versione 15.5 - Per le nuove funzionalità, vedere Visual Basic 15.5Visual Basic 15.5 / Visual Studio 2017 Version 15.5 For new features, see Visual Basic 15.5

Visual Basic 15.3 / Visual Studio 2017 versione 15.3 - Per le nuove funzionalità, vedere Visual Basic 15.3Visual Basic 15.3 / Visual Studio 2017 Version 15.3 For new features, see Visual Basic 15.3

Visual Basic 2017 / Visual Studio 2017 - Per le nuove funzionalità, vedere Visual Basic 2017Visual Basic 2017 / Visual Studio 2017 For new features, see Visual Basic 2017

Visual Basic / Visual Studio 2015 - Per le nuove funzionalità, vedere Visual Basic 14Visual Basic / Visual Studio 2015 For new features, see Visual Basic 14

Visual Basic / Visual Studio 2013 - Technology Preview della piattaforma del compilatore .NET ("Roslyn")Visual Basic / Visual Studio 2013 Technology previews of the .NET Compiler Platform (“Roslyn”)

Visual Basic / Visual Studio 2012 - Parole chiave Async e await, iteratori, attributi relativi alle informazioni sul chiamanteVisual Basic / Visual Studio 2012 Async and await keywords, iterators, caller info attributes

Visual Basic, Visual Studio 2010 - Proprietà implementate automaticamente, inizializzatori di insieme, continuazione di riga implicita, elementi dinamici, covarianza/controvarianza generica, accesso agli spazi dei nomi globaliVisual Basic, Visual Studio 2010 Auto-implemented properties, collection initializers, implicit line continuation, dynamic, generic co/contra variance, global namespace access

Visual Basic / Visual Studio 2008 - Language Integrated Query (LINQ), valori letterali XML, inferenza del tipo di variabile locale, inizializzatori di oggetto, tipi anonimi, metodi di estensione, inferenza del tipo var locale, espressioni lambda, operatore if, metodi parziali, tipi di valore nullableVisual Basic / Visual Studio 2008 Language 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 2005 - Tipo My e tipi di helper (accesso all'app, al computer, al file system, alla rete)Visual Basic / Visual Studio 2005 The My type and helper types (access to app, computer, files system, network)

Visual Basic / Visual Studio .NET 2003 - Operatori di scorrimento bit, dichiarazione di variabile del cicloVisual Basic / Visual Studio .NET 2003 Bit-shift operators, loop variable declaration

Visual Basic / Visual Studio .NET 2002 - Prima versione di Visual Basic .NETVisual Basic / Visual Studio .NET 2002 The first release of Visual Basic .NET

Visual Basic 15.8Visual Basic 15.8

Ottimizzazione della conversione da virgola mobile a IntegerOptimized floating-point to integer conversion

Nelle versioni precedenti di Visual Basic, le prestazioni della conversione dei valori Double e Single in valori Integer erano relativamente scarse.In previous versions of Visual Basic, conversion of Double and Single values to integers offered relatively poor performance. Visual Basic 15.8 migliora significativamente le prestazioni delle conversioni di valori da virgola mobile a Integer quando il valore restituito da uno dei metodi seguenti viene passato a una delle funzioni intrinseche di conversione di interi di Visual Basic (CByte, CShort, CInt, CLng, CSByte, CUShort, CUInt, CULng) o quando per il valore restituito da uno dei metodi seguenti viene eseguito il cast implicito a un tipo Integer e Option Strict è Off:Visual Basic 15.8 significantly enhances the performance of floating-point conversions to integers when you pass the value returned by any of the following methods to one of the intrinsic Visual Basic integer conversion functions (CByte, CShort, CInt, CLng, CSByte, CUShort, CUInt, CULng), or when the value returned by any of the following methods is implicitly cast to an integral type when Option Strict is set to Off:

Questa ottimizzazione consente un'esecuzione più rapida del codice, fino a due volte più rapida nei casi di esecuzione di un numero elevato di conversioni a tipi Integer.This optimization allows code to run faster -- up to twice as fast for code that does a large number of conversions to integer types. L'esempio seguente illustra alcune semplici chiamate di metodi interessati da questa ottimizzazione:The following example illustrates some simple method calls that are affected by this optimization:

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

Si noti che in questo caso i valori a virgola mobile vengono troncati anziché arrotondati.Note that this truncates rather than rounds floating-point values.

Visual Basic 15.5Visual Basic 15.5

Argomenti denominati non finaliNon-trailing named arguments

In Visual Basic 15.3 e versioni precedenti, quando una chiamata al metodo includeva argomenti in base alla posizione e al nome, gli argomenti posizionali dovevano precedere gli argomenti denominati.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. A partire da Visual Basic 15,5, gli argomenti posizionali e denominati possono trovarsi in qualsiasi ordine, purché tutti gli argomenti fino all'ultimo argomento posizionale si trovino nella posizione corretta.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. Ciò è particolarmente utile quando gli argomenti denominati vengono utilizzati per rendere il codice più leggibile.This is particularly useful when named arguments are used to make code more readable.

Ad esempio, la seguente chiamata al metodo ha due argomenti posizionali tra un argomento denominato.For example, the following method call has two positional arguments between a named argument. L'argomento denominato chiarisce che il valore 19 rappresenta un'età.The named argument makes it clear that the value 19 represents an age.

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

Modificatore di accesso ai membri Private ProtectedPrivate Protected member access modifier

Questa nuova combinazione di parole chiave definisce un membro accessibile da tutti i membri nella classe che lo contiene, oltre che dai tipi derivati dalla classe che lo contiene, ma solo se si trovano anche nell'assembly che lo contiene.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. Poiché le strutture non possono essere ereditate, è possibile applicare Private Protected solo ai membri di una classe.Because structures cannot be inherited, Private Protected can only be applied to the members of a class.

Separatore esadecimale/binario/ottali inizialeLeading hex/binary/octal separator

Visual Basic 2017 ha aggiunto il supporto del carattere di sottolineatura (_) come separatore di cifre.Visual Basic 2017 added support for the underscore character (_) as a digit separator. A partire da Visual Basic 15.5, è possibile usare il carattere di sottolineatura come separatore iniziale tra il prefisso e la cifra esadecimale, binaria o ottale.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. L'esempio seguente usa il separatore di cifra iniziali per definire 3.271.948.384 come numero esadecimale: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

Per usare il carattere di sottolineatura come separatore iniziale, è necessario aggiungere l'elemento seguente al file di progetto (*.vbproj) di Visual Basic: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

Inferenza di tupla denominataNamed tuple inference

Quando si assegna il valore di elementi di tupla provenienti da variabili, Visual Basic deduce il nome degli elementi di tupla dai nomi di variabili corrispondenti; non è necessario assegnare esplicitamente un nome a un elemento di tupla.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. L'esempio seguente usa l'inferenza per creare una tupla con tre elementi denominati, state, stateName, e 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

Nuove opzioni del compilatoreAdditional compiler switches

Il compilatore della riga di comando di Visual Basic ora supporta le opzioni -refout e -refonly per il controllo dell'output degli assembly di riferimento.The Visual Basic command-line compiler now supports the -refout and -refonly compiler options to control the output of reference assemblies. -refout definisce la directory di output dell'assembly di riferimento, mentre -refonly specifica che il risultato della compilazione può essere solo un assembly di riferimento.-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

TupleTuples

Le tuple sono una semplice struttura dei dati che viene solitamente usata per restituire più valori da una singola chiamata al metodo.Tuples are a lightweight data structure that most commonly is used to return multiple values from a single method call. In genere, per restituire più valori da un metodo, è necessario eseguire una delle operazioni seguenti:Ordinarily, to return multiple values from a method, you have to do one of the following:

  • Definire un tipo personalizzato (Class o Structure).Define a custom type (a Class or a Structure). Si tratta di una soluzione complicata.This is a heavyweight solution.

  • Definire uno o più parametri ByRef e restituire un valore dal metodo.Define one or more ByRef parameters, in addition to returning a value from the method.

Grazie al supporto per tuple di Visual Basic è possibile definire rapidamente una tupla, assegnare facoltativamente nomi semantici ai rispettivi valori e recuperare rapidamente i relativi valori.Visual Basic's support for tuples lets you quickly define a tuple, optionally assign semantic names to its values, and quickly retrieve its values. L'esempio seguente esegue il wrapping di una chiamata al metodo TryParse e restituisce una tupla.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

A questo punto è possibile chiamare il metodo e gestire la tupla restituita con codice simile al seguente.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

Valori letterali binari e separatori di cifreBinary literals and digit separators

È possibile definire un valore letterale binario usando il prefisso &B o &b.You can define a binary literal by using the prefix &B or &b. È anche possibile usare il carattere di sottolineatura _ come separatore di cifre per rendere il codice più leggibile.In addition, you can use the underscore character, _, as a digit separator to enhance readability. Nell'esempio seguente vengono usate entrambe le funzionalità per assegnare un valore Byte e visualizzarlo come un numero decimale, esadecimale e binario.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)      

Per altre informazioni, vedere la sezione dedicata alle assegnazioni di valori letterali dei tipi di dati Byte, Integer, Long, Short, SByte, UInteger, ULong e UShort.For more information, see the "Literal assignments" section of the Byte, Integer, Long, Short, SByte, UInteger, ULong, and UShort data types.

Supporto per valori di riferimento restituiti C#Support for C# reference return values

A partire dalla versione 7.0, C# supporta i valori di riferimento restituiti.Starting with C# 7.0, C# supports reference return values. Pertanto, quando la chiamata al metodo riceve un valore di riferimento restituito, lo può modificare.That is, when the calling method receives a value returned by reference, it can change the value of the reference. Visual Basic non consente di creare metodi con valori di riferimento restituiti, ma consente di usare e modificare tali valori.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.

Ad esempio, la classe Sentence seguente scritta in C# include un metodo FindNext che rileva la parola successiva in una frase che inizia con una sottostringa specificata.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. La stringa viene restituita come valore di riferimento restituito. Una variabile Boolean passata dal riferimento al metodo indica se la ricerca ha avuto esito positivo.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. A questo punto il chiamante non solo può leggere il valore restituito, ma lo può anche modificare. Tale modifica si riflette sulla classe 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 parole semplici, è possibile modificare la parola trovata nella frase usando un codice simile al seguente.In its simplest form, you can modify the word found in the sentence by using code like the following. Si noti che non si sta assegnando un valore al metodo, ma all'espressione che il metodo restituisce, ovvero il valore di riferimento restituito.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.

Esiste tuttavia un problema con questo codice. Se non viene trovata una corrispondenza, il metodo restituisce la prima parola.A problem with this code, though, is that if a match is not found, the method returns the first word. L'esempio non esamina il valore dell'argomento Boolean per determinare se viene trovata una corrispondenza. Modifica quindi la prima parola se non esiste corrispondenza.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. Nell'esempio seguente questo problema viene risolto sostituendo la prima parola con la parola stessa se non esiste corrispondenza.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.

Una soluzione migliore consiste nell'usare un metodo helper al quale il riferimento passa il valore di riferimento restituito.A better solution is to use a helper method to which the reference return value is passed by reference. Il metodo helper può quindi modificare l'argomento passato dal riferimento.The helper method can then modify the argument passed to it by reference. Nell'esempio seguente viene eseguita questa operazione.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.

Per altre informazioni, vedere Reference Return Values (Valori di riferimento restituiti).For more information, see Reference Return Values.

Visual Basic 14Visual Basic 14

NameofNameof

È possibile ottenere il nome di stringa non qualificato di un tipo o di un membro, da usare in un messaggio di errore senza definire una stringa a livello di codice.You can get the unqualified string name of a type or member for use in an error message without hard coding a string. In questo modo il codice sarà corretto anche durante il refactoring.This allows your code to remain correct when refactoring. Questa funzionalità è utile anche per l'associazione di collegamenti MVC (Modello-Vista-Controller) e la generazione di eventi di modifica di proprietà.This feature is also useful for hooking up model-view-controller MVC links and firing property changed events.

Interpolazione di stringheString interpolation

È possibile usare espressioni di interpolazione di stringhe per costruire stringhe.You can use string interpolation expressions to construct strings. Un'espressione di stringa interpolata è simile a una stringa di modello che contiene espressioni.An interpolated string expression looks like a template string that contains expressions. In relazione agli argomenti, è più facile comprendere una stringa interpolata che la formattazione composita.An interpolated string is easier to understand with respect to arguments than Composite Formatting.

Indicizzazione e accesso ai membri condizionali nullNull-conditional member access and indexing

È possibile verificare la presenza di valori null con una sintassi molto leggera prima di eseguire un'operazione di accesso ai membri (?.) o di indice (?[]).You can test for null in a very light syntactic way before performing a member access (?.) or index (?[]) operation. Questi operatori consentono di scrivere meno codice per gestire i controlli null, soprattutto per l'ordinamento decrescente delle strutture di dati.These operators help you write less code to handle null checks, especially for descending into data structures. Se l'operando di sinistra o il riferimento a un oggetto è null, le operazioni restituiscono null.If the left operand or object reference is null, the operations returns null.

Valori letterali multilineaMulti-line string literals

I valori letterali stringa possono contenere sequenze di nuove righe.String literals can contain newline sequences. Non è più necessario usare <xml><![CDATA[...text with newlines...]]></xml>.Value come soluzione alternativa.You no longer need the old work around of using <xml><![CDATA[...text with newlines...]]></xml>.Value

CommentiComments

È possibile inserire commenti dopo le continuazioni di riga implicita, all'interno delle espressioni dell'inizializzatore e tra i termini delle espressioni LINQ.You can put comments after implicit line continuations, inside initializer expressions, and among LINQ expression terms.

Risoluzione dei nomi completi più intelligenteSmarter fully-qualified name resolution

In precedenza, con un codice come Threading.Thread.Sleep(1000), Visual Basic cercava lo spazio dei nomi "Threading", individuava un'ambiguità tra System.Threading e System.Windows.Threading e quindi segnalava un errore.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 ora prende in considerazione entrambi gli spazi dei nomi possibili.Visual Basic now considers both possible namespaces together. Se si visualizza l'elenco di completamento, l'editor di Visual Studio elenca i membri di entrambi i tipi in questo elenco.If you show the completion list, the Visual Studio editor lists members from both types in the completion list.

Valori letterali data con anno all'inizioYear-first date literals

I valori letterali data possono avere il formato aaaa-mm-gg, #2015-03-17 16:10 PM#.You can have date literals in yyyy-mm-dd format, #2015-03-17 16:10 PM#.

Proprietà dell'interfaccia readonlyReadonly interface properties

È possibile implementare proprietà dell'interfaccia readonly usando una proprietà readonly.You can implement readonly interface properties using a readwrite property. L'interfaccia garantisce la funzionalità minima e le classi di implementazione non smettono di consentire l'impostazione della proprietà.The interface guarantees minimum functionality, and it does not stop an implementing class from allowing the property to be set.

TypeOf <espressione> IsNot <tipo>TypeOf <expr> IsNot <type>

Per una maggiore leggibilità del codice, ora è possibile usare TypeOf con IsNot.For more readability of your code, you can now use TypeOf with IsNot.

#Disable Warning <ID> e #Enable Warning <ID>#Disable Warning <ID> and #Enable Warning <ID>

È possibile disabilitare e abilitare avvisi specifici per le aree all'interno di un file di origine.You can disable and enable specific warnings for regions within a source file.

Miglioramenti dei commenti in formato documentazione XMLXML doc comment improvements

Quando si scrivono commenti ai documenti, si accede a Smart Editor e al supporto per la compilazione per la convalida di nomi di parametro, la corretta gestione di crefs (generics, operatori e così via), la colorazione e il refactoring.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.

Definizioni di interfacce e moduli parzialiPartial module and interface definitions

Oltre a classi e struct, è possibile dichiarare interfacce e moduli parziali.In addition to classes and structs, you can declare partial modules and interfaces.

Direttive #Region in corpi di metodo#Region directives inside method bodies

È possibile inserire delimitatori #Region...#End Region in qualsiasi punto di un file, nelle funzioni o nei corpi delle funzioni.You can put #Region…#End Region delimiters anywhere in a file, inside functions, and even spanning across function bodies.

Le definizioni Overrides sono overload implicitiOverrides definitions are implicitly overloads

Se si aggiunge il modificatore Overrides a una definizione, il compilatore aggiunge in modo implicito Overloads. In questo modo è possibile digitare meno codice nella maggior parte dei casi.If you add the Overrides modifier to a definition, the compiler implicitly adds Overloads so that you can type less code in common cases.

CObj consentito negli argomenti degli attributiCObj allowed in attributes arguments

Il compilatore generava un errore indicante che CObj(...), se usato nelle costruzioni degli attributi, non era una costante.The compiler used to give an error that CObj(…) was not a constant when used in attribute constructions.

Dichiarazione e utilizzo di metodi ambigui da interfacce diverseDeclaring and consuming ambiguous methods from different interfaces

In precedenza il codice seguente restituiva errori che impedivano di dichiarare IMock o di chiamare GetDetails (se questi erano stati dichiarati in 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

Ora il compilatore userà le normali regole di risoluzione dell'overload per scegliere l'oggetto GetDetails più appropriato da chiamare ed è possibile dichiarare le relazioni tre le interfacce in Visual Basic, come quelle mostrate nell'esempio.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.

Vedere ancheSee also