Co nowego w Visual Basic
W tym temacie wymieniono kluczowe nazwy funkcji dla każdej wersji Visual Basic z szczegółowymi opisami nowych i rozszerzonych funkcji w najnowszych wersjach języka.
Visual Basic 16.9 / Visual Studio 2019 w wersji 16.9
Aby uzyskać informacje o nowych funkcjach, zobacz Visual Basic 16.9.
Najnowszy zestaw SDK platformy .NET można pobrać ze strony pobierania platformy .NET.
Visual Basic 16.0 / Visual Studio 2019 w wersji 16.0
Aby uzyskać informacje o nowych funkcjach, zobacz Visual Basic 16.0.
Visual Basic 15.5 / Visual Studio 2017 w wersji 15.5
Aby uzyskać informacje o nowych funkcjach, zobacz Visual Basic 15.5.
Visual Basic 15.3 / Visual Studio 2017 w wersji 15.3
Aby uzyskać informacje o nowych funkcjach, zobacz Visual Basic 15.3.
Visual Basic 15 / Visual Studio 2017
Aby uzyskać informacje o nowych funkcjach, zobacz Visual Basic 2017.
Visual Basic / Visual Studio 2015
Aby uzyskać informacje o nowych funkcjach, zobacz Visual Basic 14.
Visual Basic/Visual Studio 2013
Podglądy technologii .NET Compiler Platform ("Roslyn")
Visual Basic / Visual Studio 2012
Async
i await
słowa kluczowe, iteratory, atrybuty informacji o obiektach wywołujących
Visual Basic, Visual Studio 2010
Właściwości zaimplementowane automatycznie, inicjatory kolekcji, niejawna kontynuacja wiersza, dynamiczna, ogólna wariancja co/contra, globalny dostęp do przestrzeni nazw
Visual Basic / Visual Studio 2008
Zapytanie zintegrowane z językiem (LINQ), literały XML, wnioskowanie typu lokalnego, inicjatory obiektów, typy anonimowe, metody rozszerzenia, wnioskowanie typu lokalnego var
, wyrażenia lambda, if
operator, metody częściowe, typy wartości dopuszczanych do wartości null
Visual Basic / Visual Studio 2005
My
Typy typów i pomocników (dostęp do aplikacji, komputera, systemu plików, sieci)
Visual Basic /Visual Studio .NET 2003
Operatory przesunięcia bitowego, deklaracja zmiennej pętli
Visual Basic/Visual Studio .NET 2002
Pierwsza wersja platformy Visual Basic .NET
Visual Basic 16.9 umożliwia użycie właściwości tylko inicjowania.
Visual Basic 16.0 koncentruje się na dostarczaniu większej liczby funkcji środowiska uruchomieniowego Visual Basic (microsoft.visualbasic.dll) do platformy .NET Core i jest pierwszą wersją Visual Basic skoncentrowaną na platformie .NET Core. Wiele części środowiska uruchomieniowego Visual Basic zależy od funkcji WinForms i zostaną one dodane w nowszej wersji Visual Basic.
Komentarze dozwolone w większej ilości miejsc w instrukcjach
W Visual Basic wersji 15.8 i starszych komentarze są dozwolone tylko w pustych wierszach, na końcu instrukcji lub w określonych miejscach w instrukcji, w których dozwolona jest niejawna kontynuacja wiersza. Począwszy od Visual Basic 16.0, komentarze są również dozwolone po jawnych kontynuacjach wiersza i w instrukcji w wierszu rozpoczynającym się od spacji, po której następuje podkreślenie.
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
Zoptymalizowana konwersja zmiennoprzecinkowa na liczbę całkowitą
W poprzednich wersjach Visual Basic konwersja wartości podwójnej i pojedynczej na liczby całkowite oferowały stosunkowo niską wydajność. Visual Basic 15.8 znacznie zwiększa wydajność konwersji zmiennoprzecinkowych na liczby całkowite podczas przekazywania wartości zwracanej przez dowolną z następujących metod do jednej z funkcji konwersji wewnętrznej Visual Basic całkowitej (CByte, CShort, CInt, CLng, CSByte, CUShort, CUInt, CULng) lub gdy wartość zwracana przez dowolną z poniższych metod jest niejawnie rzutowana na typ całkowity, gdy Opcja Strict jest ustawiona na Off
:
- Conversion.Fix(Double)
- Conversion.Fix(Object)
- Conversion.Fix(Single)
- Conversion.Int(Double)
- Conversion.Int(Object)
- Conversion.Int(Single)
- Math.Ceiling(Double)
- Math.Floor(Double)
- Math.Round(Double)
- Math.Truncate(Double)
Ta optymalizacja umożliwia szybsze uruchamianie kodu — maksymalnie dwa razy szybciej w przypadku kodu, który wykonuje dużą liczbę konwersji na typy całkowite. W poniższym przykładzie przedstawiono kilka prostych wywołań metod, które mają wpływ na tę optymalizację:
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
Należy pamiętać, że to obcinanie zamiast zaokrągla wartości zmiennoprzecinkowe.
Argumenty nazwane inne niż końcowe
W Visual Basic wersji 15.3 i starszych, gdy wywołanie metody obejmowało argumenty zarówno według pozycji, jak i nazwy, argumenty pozycyjne musiały poprzedzać nazwane argumenty. Począwszy od Visual Basic 15.5, argumenty pozycyjne i nazwane mogą pojawiać się w dowolnej kolejności, o ile wszystkie argumenty do ostatniego argumentu pozycyjnego są w prawidłowej pozycji. Jest to szczególnie przydatne, gdy nazwane argumenty są używane do zwiększenia czytelnego kodu.
Na przykład następujące wywołanie metody ma dwa argumenty pozycyjne między nazwanym argumentem. Nazwany argument jasno wyjaśnia, że wartość 19 reprezentuje wiek.
StudentInfo.Display("Mary", age:=19, #9/21/1998#)
Private Protected
modyfikator dostępu do elementu członkowskiego
Ta nowa kombinacja słowa kluczowego definiuje składową, która jest dostępna dla wszystkich elementów członkowskich w swojej klasie zawierającej, a także przez typy pochodzące z zawierającej klasy, ale tylko wtedy, gdy znajdują się one również w zestawie zawierającym. Ponieważ nie można dziedziczyć struktur, Private Protected
można stosować tylko do składowych klasy.
Wiodący separator szesnastkowy/binarny/ósemkowy
Visual Basic 2017 dodano obsługę znaku podkreślenia (_
) jako separatora cyfr. Począwszy od Visual Basic 15.5, można użyć znaku podkreślenia jako separatora wiodącego między prefiksem a cyframi szesnastkowymi, binarnymi lub ósemkowymi. W poniższym przykładzie użyto separatora cyfr wiodących do zdefiniowania 3 271 948 384 jako liczby szesnastkowej:
Dim number As Integer = &H_C305_F860
Aby użyć znaku podkreślenia jako separatora wiodącego, należy dodać następujący element do pliku projektu Visual Basic (*.vbproj):
<PropertyGroup>
<LangVersion>15.5</LangVersion>
</PropertyGroup>
Po przypisaniu wartości elementów krotki ze zmiennych Visual Basic wywnioskuje nazwę elementów krotki z odpowiednich nazw zmiennych; nie trzeba jawnie nazywać elementu krotki. W poniższym przykładzie użyto wnioskowania do utworzenia krotki z trzema nazwanymi elementami, state
, stateName
i capital
.
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
Dodatkowe przełączniki kompilatora
Kompilator wiersza polecenia Visual Basic obsługuje teraz opcje kompilatora -refout i -refonly w celu kontrolowania danych wyjściowych zestawów odwołań. -refout definiuje katalog wyjściowy zestawu odwołania, a -refonly określa, że tylko zestaw odniesienia ma być wyjściowy przez kompilację.
Krotki to uproszczona struktura danych, która najczęściej jest używana do zwracania wielu wartości z pojedynczego wywołania metody. Zwykle, aby zwrócić wiele wartości z metody, należy wykonać jedną z następujących czynności:
Zdefiniuj typ niestandardowy (a
Class
lub ).Structure
Jest to rozwiązanie o dużej wadze.Zdefiniuj co najmniej jeden
ByRef
parametr, oprócz zwracania wartości z metody .
obsługa krotek Visual Basic pozwala szybko zdefiniować krotkę, opcjonalnie przypisywać nazwy semantyczne do jej wartości i szybko pobierać jej wartości. Poniższy przykład opakowuje wywołanie TryParse metody i zwraca krotkę.
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
Następnie możesz wywołać metodę i obsłużyć zwróconą krotkę kodem, tak jak poniżej.
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
Literały binarne i separatory cyfr
Literał binarny można zdefiniować przy użyciu prefiksu &B
lub &b
. Ponadto można użyć znaku podkreślenia , _
jako separatora cyfr, aby zwiększyć czytelność. W poniższym przykładzie użyto obu funkcji do przypisania Byte
wartości i wyświetlenia jej jako liczby dziesiętnej, szesnastkowej i binarnej.
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)
Aby uzyskać więcej informacji, zobacz sekcję "Przypisania literału" typów danych Byte, Integer, Long, Short, SByte, UInteger, ULong i UShort .
Obsługa wartości zwracanych odwołań w języku C#
Począwszy od języka C# 7.0, język C# obsługuje wartości zwracane przez odwołanie. Oznacza to, że gdy metoda wywołująca odbiera wartość zwracaną przez odwołanie, może zmienić wartość odwołania. Visual Basic nie zezwala na tworzenie metod z wartościami zwracanymi odwołaniami, ale umożliwia używanie i modyfikowanie wartości zwracanych odwołań.
Na przykład następująca Sentence
klasa napisana w języku C# zawiera metodę FindNext
, która znajduje następne słowo w zdaniu rozpoczynającym się od określonego podciągnięcia. Ciąg jest zwracany jako wartość zwracana przez odwołanie, a Boolean
zmienna przekazana przez odwołanie do metody wskazuje, czy wyszukiwanie zakończyło się pomyślnie. Oznacza to, że oprócz odczytywania zwróconej wartości obiekt wywołujący również może go modyfikować i że modyfikacja jest odzwierciedlana w Sentence
klasie.
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();
}
}
W najprostszej formie można zmodyfikować słowo znalezione w zdaniu przy użyciu kodu, takiego jak poniżej. Należy pamiętać, że nie przypisujesz wartości do metody, ale raczej do wyrażenia zwracanego przez metodę, czyli wartości zwracanej przez odwołanie.
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.
Jednak problem z tym kodem polega na tym, że jeśli dopasowanie nie zostanie znalezione, metoda zwróci pierwsze słowo. Ponieważ w przykładzie nie jest sprawdzana wartość argumentu Boolean
w celu określenia, czy znaleziono dopasowanie, modyfikuje pierwsze słowo, jeśli nie ma dopasowania. Poniższy przykład poprawia to, zastępując pierwsze słowo samym sobą, jeśli nie ma dopasowania.
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.
Lepszym rozwiązaniem jest użycie metody pomocniczej, do której jest przekazywana wartość zwracana przez odwołanie. Metoda pomocnika może następnie zmodyfikować argument przekazany do niego przez odwołanie. Poniższy przykład to robi.
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.
Aby uzyskać więcej informacji, zobacz Odwołania wartości zwracane.
Możesz uzyskać niekwalifikowaną nazwę ciągu typu lub elementu członkowskiego do użycia w komunikacie o błędzie bez kodowania na stałe ciągu. Dzięki temu kod może pozostać poprawny podczas refaktoryzacji. Ta funkcja jest również przydatna do podłączania łączy MVC kontrolera modelu i wyzwalania zdarzeń zmienionych właściwości.
Do konstruowania ciągów można używać wyrażeń interpolacji ciągów. Wyrażenie ciągu interpolowanego wygląda jak ciąg szablonu zawierający wyrażenia. Ciąg interpolowany jest łatwiejszy do zrozumienia w odniesieniu do argumentów niż formatowanie złożone.
Dostęp warunkowy do składowych o wartości null i indeksowanie
Przed wykonaniem operacji dostępu do składowej () lub indeksu (?.
?[]
) można przetestować wartość null w sposób bardzo lekki. Te operatory ułatwiają pisanie mniejszej ilości kodu w celu obsługi kontroli wartości null, szczególnie w przypadku malenia w strukturach danych. Jeśli lewy argument operacji lub odwołanie do obiektu ma wartość null, operacje zwracają wartość null.
Literały ciągu wielowierszowego
Literały ciągu mogą zawierać sekwencje nowego wiersza. Nie potrzebujesz już starej pracy z użyciem <xml><![CDATA[...text with newlines...]]></xml>.Value
Komentarze
Komentarze można umieszczać po niejawnych kontynuacjach wierszy, wewnątrz wyrażeń inicjatora i wśród terminów wyrażeń LINQ.
Inteligentniejsze w pełni kwalifikowane rozpoznawanie nazw
Podany kod, taki jak Threading.Thread.Sleep(1000)
, Visual Basic używany do wyszukiwania przestrzeni nazw "Threading", wykrył, że był niejednoznaczny między System.Threading i System.Windows. Wątkowanie, a następnie zgłaszanie błędu. Visual Basic uwzględnia teraz obie możliwe przestrzenie nazw. Jeśli zostanie wyświetlona lista uzupełniania, edytor Visual Studio wyświetli listę elementów członkowskich z obu typów na liście uzupełniania.
Literały daty pierwszego roku
Literały daty można mieć w formacie rrrr-mm-dd, #2015-03-17 16:10 PM#
.
Właściwości interfejsu tylko do odczytu
Właściwości interfejsu tylko do odczytu można zaimplementować przy użyciu właściwości readwrite. Interfejs gwarantuje minimalną funkcjonalność i nie uniemożliwia implementowania klasy zezwalającej na ustawienie właściwości.
Aby uzyskać większą czytelność kodu, można teraz używać z programem TypeOf
IsNot
.
identyfikator> ostrzeżenia <#Disable i identyfikator ostrzeżenia <#Enable>
Możesz wyłączyć i włączyć określone ostrzeżenia dla regionów w pliku źródłowym.
Ulepszenia komentarzy dokumentu XML
Podczas pisania komentarzy do dokumentu uzyskujesz inteligentny edytor i kompilujesz obsługę walidacji nazw parametrów, prawidłowej crefs
obsługi (typów ogólnych, operatorów itp.), kolorowania i refaktoryzacji.
Częściowe definicje modułów i interfejsów
Oprócz klas i struktur można deklarować częściowe moduły i interfejsy.
dyrektywy #Region wewnątrz treści metod
Można umieścić #Region...#End ograniczniki regionów w dowolnym miejscu w pliku, wewnątrz funkcji, a nawet obejmujące całe ciała funkcji.
Definicje przesłonięć są niejawnie przeciążenia
Overrides
Jeśli dodasz modyfikator do definicji, kompilator niejawnie dodaOverloads
, aby w typowych przypadkach można było wpisać mniej kodu.
CObj dozwolone w argumentach atrybutów
Kompilator używany do podania błędu, że obiekt CObj(...) nie był stałym elementem używanym w konstrukcjach atrybutów.
Deklarowanie i używanie niejednoznacznych metod z różnych interfejsów
Wcześniej poniższy kod zwracał błędy, które uniemożliwiły deklarowanie lub wywoływanie IMock
wywołań GetDetails
(jeśli zostały one zadeklarowane w języku 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
Teraz kompilator użyje normalnych reguł rozwiązywania przeciążenia, aby wybrać najbardziej odpowiednie GetDetails
do wywołania, i można zadeklarować relacje interfejsu w Visual Basic, tak jak pokazane w przykładzie.