Język VB.NET ma wiele cech wspólnych z językami programowania Visual Basic i BASIC.
Nazwa
Nazwa może być myląca, szczególnie dla tych, którzy słyszeli o ograniczeniach Visual Basica w wersji do 6.
Zaadaptowanie VB do platformy .NET częściowo wymusiło, a częściowo pozwoliło na dość duże zmiany, znacznie poszerzając możliwości języka.
Jako że jednym z celów (lub też ubocznym skutkiem) stworzenia platformy .NET było danie programiście wyboru odnośnie do stosowania składni wybranego przez siebie języka przy zachowaniu funkcjonalności, język Visual Basic .NET ma funkcjonalność bardzo podobną co C#, a kod produkowany przez kompilatory obu języków często jest identyczny.
Składnia
Język wywodzi się z rodziny BASIC.
Jego podstawowe cechy odróżniające od rodziny C to:
jedno wyrażenie występuje w jednej linii fizycznej (CR – znak końca linii). W związku z tym domyślnie nie występuje logicznie znak końca linii w postaci ";" jak w językach rodziny C. Dwie instrukcje w jednej linii fizycznej można w razie potrzeby zapisać używając składni "Instrukcja1 : Instrukcja2" natomiast przeniesienie do następnej linii fizycznej można w razie potrzeby zastosować używając sekwencji " _" (spacja – podkreślenie) na końcu linii fizycznej.
NazwaKonstrukcji [Opcje]
....
End NazwaKonstrukcji
np.
WhileTrue...EndWhileDoWhileTrueDoUntilFalseDoDo...LoopUntilFalseLoopWhileTrueLoopLoopForxAsDouble=-3.5To30ForyAsInteger=10To0Step-2...' KomentarzNext' Opcjonalnie Next yNext'opcjonalnie Next xClass...EndClass
Tablice definiuje się np. tak:
DimTab(4,9)AsString
co wyklucza potrzebę używania nawiasów kwadratowych w składni, a oznacza zdefiniowanie tablicy o wymiarach 5 na 10 – bo z zakresu 0..4,0..9. Wynika to z faktu, że Visual Basic (nie VB.NET) pozwalał na zdefiniowanie tablicy (_od_ To _do_) np. (5 To 100) lub używając tylko _do_ (np. (100) co implikowało (0 To 100)). Niestety tzw. Common Type System narzuca kompilatorom ograniczanie sposobu indeksowania tablic do tablic zaczynających się indeksem zerowym co wyklucza sens składni _od_ To _do_ choć sama wirtualna maszyna CIL pozwala na tworzenie tablic o indeksie początkowym innymi niż 0.
Tablice można też deklarować w stylu C (nadal 0-indeksowo).
DimTab(4)(9)AsString
gdzie sugerujemy, że każdy Tab(i) prowadzi na tablicę 10-elementową.
Wymaga to inicjalizacji zmiennej Tab Tablica(Array), każdego elementu tablicy tablica, i każdego elementu tej tablicy Cosiem.
Trzeba jednak pamiętać, że tablica T()() oraz T(,) mają odzwierciedlenie w postaci innych typów w prekompilowanym pseudokodzie CIL.
generyczność znana np. z Ada 95 czy C++ jako <template>
brak operatora porównania "==" czy operatora przypisania ":="
Występuje jeden operator "=" oznaczający przypisanie lub porównanie.
Kompilator przyjmuje, że jeżeli wyrażenie ma postać
Zmienna=Dalszewyrażenie
Lub
DimZmiennaAsTyp=Dalszewyrażenie
oznacza to przypisanie wartości z prawej strony do zmiennej Zmienna.
W innych przypadkach "=" porównuje wyrażenia zwracając wartość boolowską.
np.
DimAAsBoolean,B,CAsIntegerA=B=C
oznacza, że wartości liczb B i C zostaną porównane, a wynik tego porównania zostanie zwrócony jako 'True' lub 'False' a to z kolei przypisane do zmiennej A.
Podobnie w składni warunkowej
Jest to przydatne gdy dana funkcja (procedura) przyjmuje dużą ilość argumentów opcjonalnych.
Łańcuchy znaków zamykane są w cudzysłowach ("). Jeżeli trzeba w Stringu użyć cudzysłowu używa się podwójnego znaku cudzysłowu
DimaAsString="A wtedy on powiedział ""Dajcie mi spokój."""' A zawiera: A wtedy on powiedział "Dajcie mi spokój."
Nie występują znaki specjalne w formacie \" \n itp.
DimbAsString="zmienna x="""&a&""""&Chr(10)&_
"następna linijka."'b zawiera: zmienna x="A wtedy on powiedział "Dajcie mi spokój.""' następna linijka.
W tej kwestii rodzina Basic zachowuje się podobnie do języka Ada.
Znak 10 to znak końca linii tak więc Chr(10) daje znak końca linii. Chr() zwracający znak o kodzie podanym jako argument jest funkcją inline, także w trakcie kompilacji zamienia się w znak końca linii (wniosek: nie różni się prędkością wykonywania kodu od znanego z C "\n").
Wbudowana w składnię obsługa synchronizacji wątków. – SyncLock
Dalsze przykładowe programy
Prosty program napisany w języku VB.NET. Po jego skompilowaniu i uruchomieniu zobaczymy napis „Hello world!”.
ImportsSystemPublicClassPrzykladowaKlasaPublicSharedSubMain()'Procedura współdzielona między instancjami klasySystem.Console.WriteLine("Hello world")ForiAsInteger=1To10System.Console.WriteLine("To jest linia "&i)NextEndSubEndClass
Lub
ModuleNazwaModulu'Moduł jako bezobiektowy element grupujący w przestrzeń nazw.PublicSubMain()' nie ma słowa Shared bo moduł wydziela kod, natomiast' nie ma możliwości powołania obiektu typu modułowegoSystem.Console.WriteLine("Hello world")ForiAsInteger=1To10System.Console.WriteLine("To jest linia "&i)NextEndSubEndModule
Zamiast pisać System.Console.WriteLine można wykorzystać specjalną składnię do pracy z obiektem:
PublicSubMain()WithSystem.Console.WriteLine("Hello world")ForiAsInteger=1To10.WriteLine("To jest linia "&i)NextEndSub
Kolejny przykładowy program demonstruje technikę programowania interfejsu graficznego (GUI). Po jego skompilowaniu i uruchomieniu system operacyjny utworzy okienko aplikacji.
ImportsSystem'Domyślnie szukaj elementów w SystemImportsSystem.Windows.Forms'a także w System.Windows.FormsPublicClassPrzykladoweOknoInheritsForm'Konstruktor z dziedziczeniem konstruktora macierzystegoSubNew()MyBase.New()EndSubPublicSharedSubMain()Application.Run(NewPrzykladoweOkno());EndSubEndClass
Następny przykład pokazuje konstrukcję interfejsu, czyli rodzaju nagłówka klasy definiującego mechanizmy implementowane przez klasę.
Klasa, która implementuje pewien interfejs (co programista może łatwo sprawdzić (If TypeOf NazwaObiektu Is IJakisInterfejs)), zobowiązuje się posiadać zaadaptowane do swoich warunków wszystkie procedury, funkcje, właściwości, zdarzenia itd. określone w interfejsie.