Visual Basic.NET und Visual Basic 6 Ralf Westphal MSDN Regional Director, freier Fachautor & Berater
Agenda Einordnung von VB6 Microsoft.NET Framework Visual Basic.NET
VB.NET kann man nicht isoliert als Programmiersprache verstehen, sondern nur als Teil der.NET-Plattform.
Von VB6 zu VB.NET VB6 Allgm. Sprachen.NET CLR.NET Sprachen VB.NET
Was macht VB6 aus? Einfache GUI-Gestaltung Einfacher DB-Umgang Einfacher Umgang mit Strings Einfache APIs Intrinsische Funktionen, Declare, COM Einfache Erzeugung von Komponenten ActiveX-DLLs, UserControls Einfache Syntax dot-Syntax, keine Zeiger, Kontrollstrukturen Einfache Semantik Klassen, Objekt-Destruktor, Eval. Logischer Ausdrücke
VB6 allgemein Syntax Semantik GUI RAD Datenbankzugriff Typsystem OO-/Komponententechnologie Standardbibliothek APIs
Von VB6 zu VB.NET VB6 Sprachen allgm..NET CLR.NET Sprachen VB.NET
Programmiersprachen allgemein Was gehört zu einer Sprache? Syntax Semantik Programmierparadigma Was gehört nicht zu einer Sprache? UI-Gestaltung Datenbankzugriff Typsystem Standardbibliothek APIs
Von VB6 zu VB.NET VB6 Allgm. Sprachen.NET CLR.NET Sprachen VB.NET
COM Runtime (OLE32.DLL) Microsoft Transaction Server (MTXEX.DLL) Layer (VBRUNxx.DLL) (ATL.DLL) Class-LoaderRemoting KontextConcurrencyTransaktionenSprach-Integration COM+ Runtime (OLE32.DLL) Layer (VBRUNxx.DLL) (ATL.DLL) Common Language Runtime (MSCOREE.DLL) (MSCORLIB.DLL) Warum eine Runtime? Einheitliches Integrationsmodell
.NET Framework Base Class Library Common Language Specification Common Language Runtime Data and XML VBC++C# Visual Studio.NET Web Services JScript… User Interface
Common Language Runtime Class Loader IL to Native Compilers Code Manager Garbage Collector Security EngineDebug EngineType CheckerException ManagerThread SupportCOM Marshaler
Compiler erzeugen keinen native Code sondern eine prozessorunabhängige Zwischensprache Sprachintegration erfolgt auf IL-Codeebene MSIL – Microsoft Intermediate Language IL-Code wird vor der Ausführung immer (!) durch Compiler in echten Maschinencode übersetzt Unabhängigkeit von Hardwareplattformen Unter Windows CE bereits mit einem IL-Vorläufer im Einsatz Basics Microsoft Intermediate Language
Hello, World! C# using System; namespace HelloWorld { public class Class1 { public static void Main() { Console.WriteLine("Hello, World!"); } VB.NET Imports System Namespace HelloWorld Class Class1 Shared Sub Main() Console.WriteLine("Hello, World!") End Sub End Class End Namespace Alternativ: Module Module1 Sub Main() Sub Main() Console.WriteLine("Hello, World!") Console.WriteLine("Hello, World!") End Sub End Sub End Module
Hello, World: VB.NET IL.namespace Project3.HelloWorld {.class private auto ansi Class1.class private auto ansi Class1 extends [mscorlib]System.Object extends [mscorlib]System.Object {.method public specialname rtspecialname.method public specialname rtspecialname instance void.ctor() il managed instance void.ctor() il managed {.custom instance void [mscorlib]System.Diagnostics.DebuggerStepThroughAttribute::.ctor() = ( ).custom instance void [mscorlib]System.Diagnostics.DebuggerStepThroughAttribute::.ctor() = ( ).maxstack 8.maxstack 8 IL_0000: ldarg.0 IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: ret IL_0006: ret }.method public static void Main() il managed.method public static void Main() il managed {.maxstack 1.maxstack 1.locals init ([0] class System.Object[] _Vb_t_record_0).locals init ([0] class System.Object[] _Vb_t_record_0) IL_0000: nop IL_0000: nop IL_0001: ldstr "Hello, World!" IL_0001: ldstr "Hello, World!" IL_0006: call void [mscorlib]System.Console::WriteLine(class System.String) IL_0006: call void [mscorlib]System.Console::WriteLine(class System.String) IL_000b: nop IL_000b: nop IL_000c: ret IL_000c: ret } }}.namespace Project3 {.class private auto ansi _vbProject.class private auto ansi _vbProject extends [mscorlib]System.Object extends [mscorlib]System.Object {.custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.Globals/Globals$StandardModuleAttribute::.ctor() = ( ).custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.Globals/Globals$StandardModuleAttribute::.ctor() = ( ).method public static void _main(class System.String[] _s) il managed.method public static void _main(class System.String[] _s) il managed {.entrypoint.entrypoint.maxstack 8.maxstack 8 IL_0000: call void Project3.HelloWorld.Class1::Main() IL_0000: call void Project3.HelloWorld.Class1::Main() IL_0005: ret IL_0005: ret } }}
Hello, World: C# IL.namespace HelloWorld {.class public auto ansi Class1 extends [mscorlib]System.Object {.method public hidebysig static void Main() il managed {.entrypoint.maxstack 8 IL_0000: ldstr "Hello, World!" IL_0005: call void [mscorlib]System.Console::WriteLine(class System.String) IL_000a: ret }.method public hidebysig specialname rtspecialname instance void.ctor() il managed {.maxstack 8 IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: ret }
Hello, World: VB.NET IL (Alternativ).namespace HelloWorld {.class private auto ansi Module1.class private auto ansi Module1 extends [mscorlib]System.Object extends [mscorlib]System.Object {.custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.Globals/Globals$StandardModuleAttribute::.ctor() = ( ).custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.Globals/Globals$StandardModuleAttribute::.ctor() = ( ).method public static void Main() il managed.method public static void Main() il managed {.maxstack 1.maxstack 1.locals init ([0] class System.Object[] _Vb_t_record_0).locals init ([0] class System.Object[] _Vb_t_record_0) IL_0000: nop IL_0000: nop IL_0001: ldstr "Hello, World!" IL_0001: ldstr "Hello, World!" IL_0006: call void [mscorlib]System.Console::WriteLine(class System.String) IL_0006: call void [mscorlib]System.Console::WriteLine(class System.String) IL_000b: nop IL_000b: nop IL_000c: ret IL_000c: ret } }.class private auto ansi _vbProject.class private auto ansi _vbProject extends [mscorlib]System.Object extends [mscorlib]System.Object {.custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.Globals/Globals$StandardModuleAttribute::.ctor() = ( ).custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.Globals/Globals$StandardModuleAttribute::.ctor() = ( ).method public static void _main(class System.String[] _s) il managed.method public static void _main(class System.String[] _s) il managed {.entrypoint.entrypoint.maxstack 8.maxstack 8 IL_0000: call void ConsoleApplication9.Module1::Main() IL_0000: call void ConsoleApplication9.Module1::Main() IL_0005: ret IL_0005: ret } }}
Sämtlicher Code wird unter Aufsicht der Common Language Runtime ausgeführt Runtime führt Sicherheitsüberprüfungen aus Runtime übernimmt Speicherverwaltung und Fehlerbehandlung (Garbage Collection) Runtime führt Versionsprüfungen aus Dieser Code wird als Managed Code bezeichnet Basics Managed Code
Von VB6 zu VB.NET VB6 Allgm. Sprachen.NET CLR.NET Sprachen VB.NET
Das Typsystem wandert vom Compiler in die Runtime Typen werden eindeutig ein String unter C# und ein String unter VB.NET sind identisch Sprachen werden interoperabel, da sie das gleiche Typsystem benutzen CTS – Common Type System Basics Common Type System
Object Value Type Enum Type String Array Exception Boolean Byte Char Currency DateTime Decimal Double Guid Int16 Int32 Int64 SByte Single TimeSpan TypedRef. UInt16 UInt32 UInt64 Void Delegate Typen im Namespace System Common Type System Das Objektmodell
Zwei Arten von Typen Value (struct) Reference (class) Variable enthält WertReferenz Speicher StackHeap Initialisiert mit Alles 0 Konstante: nothing Zuweisung kopiert Wertkopiert Referenz Dim i as integer = 123 Dim s as string _ = "Hello world" 123 i s "Hello world" 123 j t Dim j as integer = i Dim t as string = s
Boxing und Unboxing Jeder Datentyp kann als Objekt gespeichert oder übergeben werden Jeder Datentyp kann als Objekt gespeichert oder übergeben werden Dim i as integer = 123 Dim o as object = i Dim j as integer = Ctype(o, Integer) 123 io 123 System.Int32 }Boxing 123 j }Unboxing
.NET Framework ASPVB FormsMFC & ATL Windows API Warum ein Framework? Einheitliches Programmiermodell
System System.DataSystem.Xml System.Web Globalization Diagnostics Configuration Collections Resources Reflection Net IO Threading Text ServiceProcess Security Design ADO SQLTypes SQL XPath XSLT Runtime InteropServices Remoting Serialization ConfigurationSessionState CachingSecurity Services Description Discovery Protocols UI HtmlControls WebControls System.Drawing Imaging Drawing2D Text Printing System.WinForms DesignComponentModel Base Class Library
Gemeinsamer Nenner aller.NET Sprachen Codeerzeugung Optimierung durch JITer Common Type System Garbage Collection COM-Interop, P/Invoke Sicherheitsinfrastruktur Attribute Ausnahmebehandlung Multithreading Standardbibliothek
Sprachen werden gleichwertig, da alle Compiler MSIL-Code erzeugen eine C# Klasse kann von einer VB.NET Klasse abgeleitet sein einheitliche Fehlerbehandlung Compilerbau wird einfacher kein eigenes Typsystem Sprachen sind per Definition interoperabel keine Standardbibliothek kein Codeoptimierungspass Basics Implikationen
Von VB6 zu VB.NET VB6 Allgm. Sprachen.NET CLR.NET Sprachen VB.NET
Mit den.NET Sprachen hat das VB- Konzept gewonnen dot-Syntax Einfache Stringbehandlung uvm. Mit VB.NET verliert VB seine Alleinstellungsmerkmale VB.NET Die gute und die schlechte Nachricht
VB.NET Was gehört zu VB.NET? Syntax Semantik Programmierparadigma Was gehört zum.NET Framework? UI-Gestaltung Datenbankzugriff Typsystem Standardbibliothek APIs
Was ist neu durch VB.NET? Tiefgreifende, echte OO-Konzepte Namespaces Strukturierte Ausnahmebehandlung Multithreading uvm.
Public Class Mitarbeiter End Interface Public Function Gehalt() As Double... End Function Public Class Arbeiter End Interface Inherits Mitarbeiter Public Property Zulage() As Double... End Property Implementation Inheritance
Nur Einfachvererbung Parametrierte Konstruktoren Instanz- und Klassen-Member (shared) Alle Methoden virtuell per default Abstrakte und finale Klassen/Member
Overloading Implementation einer Methode mehrfach mit dem selben Namen, aber immer eindeutiger Signatur Overloads Public Sub Display(ByVal theString As String) Overloads Public Sub Display(ByVal theDouble As Double) Overloads Public Sub Display(byVal theInteger As Integer) Alternative zu optionalen Parametern.
Polymorphy Public Class Mitarbeiter End Interface Overridable Public Function Gehalt() As Double Gehalt = Stunden * Stundenlohn End Function Public Class Arbeiter End Interface Inherits Mitarbeiter Overrides Function Gehalt() As Double Gehalt = Stunden * (Stundenlohn + Zulage) End Function
Polymorphy Neudefinition der Implementation einer Basisklassenmethode in einer abgeleiteten Klasse Muss in Basisklasse zugestanden werden (Overridable) Signatur bleibt gleich Verdeckt Basisklassenimplementation Kann aber über MyBase aufgerufen werden
Interface Inheritance Interface erbt von Interface Public Interface Interface1 End Interface Public Sub M1() Public Property P1 As String Public Interface Interface2 End Interface Inherits Interface1 Public Sub M2() Public Property P2 As String
Interface Inheritance Klasse implementiert und erbt Interface Public Class Arbeiter End Class Implements Mitarbeiter Public Sub Einkommen() As Double Implements Mitarbeiter.Gehalt.... End Sub Public Interface Mitarbeiter End Interface Public Sub Gehalt() As Double Public Class Vorarbeiter End Class Inherits Arbeiter Erbt auch das Interface und die Implementation von Mitarbeiter
Interface Inheritance Echte Interfaces Jede Klasse kann beliebig viele Interfaces implementieren Vererbung von Interfaces Ableitung neuer Interfaces Abgeleitete Klassen erben auch Interfaces Beliebige Zuordnung von Methoden der Klasse an Interface-Methoden
Strukturen Structure Point Private _x, _y As Double Public Sub New(ByVal x As Double, ByVal y As Double) _x = x : _y = y End Sub Public Property x() As Double Get Return _x End Get Set(ByVal Value As Double) _x = Value End Set End Property Public Overrides Function ToString() As String Return "(" & _x & ", " & _y & ")" End Function End Structure Zusammenschluss von Daten und Code Zusammenschluss von Daten und Code Werttyp Werttyp Keine Vererbung Keine Vererbung Leichtgewichtiger Datencontainer Leichtgewichtiger Datencontainer
Ausnahmebehandlung Try auszuführende Anweisungen Catch e As COMException Fehlerbehandlung Catch e As Exception... Catch When Err.Number = 5... Catch... Finally Abschließende Behandlung, auch ohne Fehler End Try
Ausnahmebehandlung Basiert auf Exception-Objekt/Klasse Eigene Exception-Klassen möglich Blockorientierte Fehlerbehandlung Garantierte Nachbehandlung (finally) Fehler während der Fehlerbehandlung (catch) müssen ebenfalls abgefangen werden Nicht behandelte Fehler werden im Call- Stack hochgereicht
Delegates DelegateEmpfänger Delegate n:1 Empfänger Multicast Delegate n:m Empfänger DelegateEmpfänger 1:1 Empfänger Multicast Delegate Empfänger 1:n
Delegates Delegate Sub MySubDelegate(ByVal x As Integer) Class MyClass Sub MySub(ByVal x As Integer) MessageBox.Show("Der Wert von X ist:" & CStr(x)) End Sub End Class Sub Test Dim mc As New MyClass Dim msd As New MySubDelegate(AddressOf mc.MySub) msd.Invoke(10) msd(10) End Sub
Delegates Dim TB1 As TextBox Dim TB2 As TextBox Protected Sub MyHandler(ByVal Sender As Object, ByVal e As System.EventArgs) Dim TB As TextBox TB = CType(sender, TextBox) End Class AddHandler TB1.TextChanged, New System.EventHandler(AddressOf MyHandler) AddHandler TB2.TextChanged, New System.EventHandler(AddressOf MyHandler)
Delegates Typisierte Funktionszeiger Sind selbst Typen und damit Objekte Basis für Ereignisbehandlung Reale Funktion muss gleiche Signatur haben WithEvents gibt es weiterhin
Attribute Public Class AutorAttribute Inherits Attribute Public name As String Public project As String Public Sub New(ByVal name As String) Me.name = name End Sub End Class Structure Point... End Structure
Attribute Runtime/Design-Time Informationen für Typen und deren Elemente Vollständig erweiterbar Ein Attribut ist eine Klasse, die von System.Attribute abgeleitet wurde Attribute werden erst instanziert, wenn darauf zugegriffen wird Code ist self contained Keine neuen Schlüsselwörter oder pragma Keine zusätzlichen Dateien, z.B.:.IDL,.DEF Zugriff zur Laufzeit über Reflection API Beispiele Wird im Framework an vielen Stellen benutzt: XML, Web Services, Security, Serialization, Component Model, COM und P/Invoke Interop … URL für Dokumentation einer Klasse Transaction context einer Methode Wie wird in XML persistiert
Multithreading Class Foo Sub Baz() Console.WriteLine("Foo Baz is running on another thread") End Sub End Class Sub main() Dim oFoo As Foo oFoo = New Foo() Dim otter As ThreadStart otter = New ThreadStart(AddressOf oFoo.Baz) Dim oThread As Thread oThread = New Thread(otter) oThread.Start End Sub
Multithreading Thread-Funktionen Instanz- oder Klassen-Methode Werden per ThreadStart-Delegate übergeben Keine Parameter Kein Funktionsresultat Cross-Thread-Aufrufe sind transparent Thread-Kontrolle über Instanz oder Klasse z.B. myThread.Stop
Was ändert sich mit VB.NET? 1/2 Syntax Andere Property-Syntax Structure statt Type Volle Qualifizierung von Enum-Konstanten Typzuweisung mit mehreren Vars bei Dim Klammern bei Sub/Function-Aufrufen Semantik Gültigkeitsbereich von Blockvariablen Indeterministische Finalisation Keine statischen Sub/Function mehr ByVal ist default Gleichstellung von Member-Variablen und Property- Methoden Default-Methoden müssen Eigenschaften mit einem Param. sein Variant entfällt
Was ändert sich mit VB.NET? 2/2 Anweisungen/Funktionen Kein Gosub, On/Gosub, On/Goto mehr Open/Close etc. jetzt Funktionen Kein IsMissing mehr Umgebung Keine Tag-Eigenschaft mehr bei Steuerelementen Keine Steuerelementfelder mehr Keine fensterlosen Steuerelemente mehr uvm.
Von VB6 zu VB.NET Conversion Wizard Funktioniert in Beta 2 noch unzureichend Probleme vor allem mit UI-bezogenem Code COM-Interop VB6 COM-Komponenten aus.NET Programmen nutzen.NET Komponenten in VB6-Programmen nutzen Nur komponentenbasierte Anwendungen werden einigermaßen schmerzfrei migriert werden können.
Haben Sie sich auch so an VB6 gewöhnt? Dann ist es jetzt Zeit, auf.NET umzusteigen!
Call to Action.NET lernen Nehmen Sie sich Zeit, jede Woche ein wenig dazu zu lernen Evaluieren Sie gleichermaßen C# und VB.NET Probieren Sie den Conversion Wizard aus Stellen Sie sicher, dass Ihre Anwendungen komponentenbasiert sind
Fragen!? Uff...
Mehr Informationen Dan Appleman: Moving to VB.NET: Strategies, Concepts, and Code; APress 2001 Ralf Westphal: Bist du es, Visual Basic? Teil 1 bis 4; Artikelserie in BasicPro 6/00 ff
VB.NET Quellen 1/2 What's New in Visual Basic (TechEd Präsentation) Visual Basic.NET: New Programming Model and Language Enhancements Boost Development Power Visual Studio Enables the Programmable Web Visual Basic.NET Upgrade Roadmap The Transition from Visual Basic 6.0 to Visual Basic.NET sp sp 10 More Ways to Prepare for VB.NET h_0103.asp h_0103.asp Get Your Designs in Gear for VB.NET asp asp Drill Down on VB.NET 2.asp 2.asp
VB.NET Quellen 2/2 An Introduction to Threading in VB.NET ZaVjEiid0J0l7LCYvBGK An Introduction to Threading in VB.NET ZaVjEiid0J0l7LCYvBGK ZaVjEiid0J0l7LCYvBGK ZaVjEiid0J0l7LCYvBGK Object Oriented Features in VB.NET ZaVjEiid0J0l7LCYvBGK Object Oriented Features in VB.NET ZaVjEiid0J0l7LCYvBGK ZaVjEiid0J0l7LCYvBGK ZaVjEiid0J0l7LCYvBGK VB.NET Delegates ZaVjEiid0J0l7LCYvBGK VB.NET Delegates ZaVjEiid0J0l7LCYvBGK ZaVjEiid0J0l7LCYvBGK ZaVjEiid0J0l7LCYvBGK Polymorphism in VB.NET ZaVjEiid0J0l7LCYvBGK Polymorphism in VB.NET ZaVjEiid0J0l7LCYvBGK ZaVjEiid0J0l7LCYvBGK ZaVjEiid0J0l7LCYvBGK Visual Basic.NET: Tracing, Logging, and Threading Made Easy with.NET Visual Basic.NET: Tracing, Logging, and Threading Made Easy with.NET New Features in Visual Basic.NET: Variables, Types, Arrays, and Properties New Features in Visual Basic.NET: Variables, Types, Arrays, and Properties Exploiting New Language Features in Visual Basic.NET, Part 2 Exploiting New Language Features in Visual Basic.NET, Part Visual Basic.NET - 10 More RAD Years Visual Basic.NET - 10 More RAD Years Die Qual der Wahl der Sprache Die Qual der Wahl der Sprache
Glossar CLR – Common Language Runtime: gemeinsame Laufzeitumgebung für alle.NET Anwendungen. CG – Garbage Collection: Sie sorgt dafür, das Speicher, der von einem Programm angefordert und benutzt wurde automatisch wieder freigegeben wird. Vorsicht beim Programmieren: Die GC bestimmt, wann Speicher physikalisch freigegeben wird. Deshalb sollten teure Resourcen - wie bspw. Datenbankverbindungen - explizit innerhalb einer eigens dafür geschriebenen Methode entsorgt werden. Diese Methode sollte immer dann aufgerufen werden, wenn die Resourcen unmittelbar freigegeben werden sollen. MSIL – Microsoft Intermediate Language JIT – Just in time Managed Code: In der.NET Plattform wird kein nativer Code mehr erzeugt. Stattdessen generieren Compiler unter.NET eine Zwischensprache (MSIL), die dann unter Aufsicht der CLR bei Bedarf (JIT) in nativen Code übersetzt und ausgeführt wird. Deshalb wird der von den Compilern erzeugte Code auch Managed Code genannt.
Empower people through great software any time, any place, and on any device