Visual Basic.NET und Visual Basic 6 Ralf Westphal MSDN Regional Director, freier Fachautor &...

Preview:

Citation preview

Visual Basic .NETund Visual Basic 6

Ralf WestphalMSDN Regional Director,

freier Fachautor & Berater

ralfw@ralfw.de

Von VB6 zu VB.NET

VB6VB6

Allgm. SprachenAllgm. Sprachen

.NET CLR.NET CLR

.NET Sprachen.NET Sprachen

VB.NETVB.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

VB6VB6

Sprachen allgm.Sprachen allgm.

.NET CLR.NET CLR

.NET Sprachen.NET Sprachen

VB.NETVB.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

VB6VB6

Allgm. SprachenAllgm. Sprachen

.NET CLR.NET CLR

.NET Sprachen.NET Sprachen

VB.NETVB.NET

COM Runtime(OLE32.DLL)

Microsoft Transaction

Server(MTXEX.DLL)

Layer(VBRUNxx.DLL)

(ATL.DLL)

Class-LoaderClass-LoaderRemotingRemoting

KontextKontextConcurrencyConcurrency

TransaktionenTransaktionen

Sprach-Sprach-IntegrationIntegration

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

VB C++ C#V

isual S

tud

io.N

ET

WebServices

JScript …

UserInterface

Common Language Runtime

Class Loader

IL to NativeCompilers

CodeManager

GarbageCollector

Security Engine Debug Engine

Type Checker Exception Manager

Thread Support COM 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 einemIL-Vorläufer im Einsatz

BasicsMicrosoft 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:Alternativ:

Module Module1Module Module1

Sub Main()Sub Main()

Console.WriteLine("Hello, World!")Console.WriteLine("Hello, World!")

End SubEnd Sub

End ModuleEnd Module

Hello, World: VB.NET IL.namespace Project3.HelloWorld.namespace Project3.HelloWorld{{ .class private auto ansi Class1.class private auto ansi Class1 extends [mscorlib]System.Objectextends [mscorlib]System.Object {{ .method public specialname rtspecialname .method public specialname rtspecialname instance void .ctor() il managedinstance void .ctor() il managed {{ .custom instance void [mscorlib]System.Diagnostics.DebuggerStepThroughAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [mscorlib]System.Diagnostics.DebuggerStepThroughAttribute::.ctor() = ( 01 00 00 00 ) .maxstack 8.maxstack 8 IL_0000: ldarg.0IL_0000: ldarg.0 IL_0001: call instance void [mscorlib]System.Object::.ctor()IL_0001: call instance void [mscorlib]System.Object::.ctor() IL_0006: retIL_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: nopIL_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: nopIL_000b: nop IL_000c: retIL_000c: ret }} }}}}

.namespace Project3.namespace Project3{{ .class private auto ansi _vbProject.class private auto ansi _vbProject extends [mscorlib]System.Objectextends [mscorlib]System.Object {{ .custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.Globals/Globals$StandardModuleAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.Globals/Globals$StandardModuleAttribute::.ctor() = ( 01 00 00 00 ) .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: retIL_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 .namespace HelloWorldHelloWorld{{ .class private auto ansi Module1.class private auto ansi Module1 extends [mscorlib]System.Objectextends [mscorlib]System.Object {{ .custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.Globals/Globals$StandardModuleAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.Globals/Globals$StandardModuleAttribute::.ctor() = ( 01 00 00 00 ) .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: nopIL_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: nopIL_000b: nop IL_000c: retIL_000c: ret }} }}

.class private auto ansi _vbProject.class private auto ansi _vbProject extends [mscorlib]System.Objectextends [mscorlib]System.Object {{ .custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.Globals/Globals$StandardModuleAttribute::.ctor() = ( 01 00 00 00 ) .custom instance void [Microsoft.VisualBasic]Microsoft.VisualBasic.Globals/Globals$StandardModuleAttribute::.ctor() = ( 01 00 00 00 ) .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: retIL_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

BasicsManaged Code

Von VB6 zu VB.NET

VB6VB6

Allgm. SprachenAllgm. Sprachen

.NET CLR.NET CLR

.NET Sprachen.NET Sprachen

VB.NETVB.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

BasicsCommon 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 imNamespaceSystem

Common Type SystemDas Objektmodell

Zwei Arten von Typen

Value (struct) Reference (class)

Variable enthält Wert Referenz

Speicher Stack Heap

Initialisiert mit Alles 0 Konstante: nothing

Zuweisung kopiert Wert kopiert Referenz

Dim Dim i i as integer as integer = 123= 123Dim Dim s s as string _as string _

= = "Hello world""Hello world"

123123ii

ss "Hello world""Hello world"

123123jj

tt

Dim Dim j j as integer as integer = i= iDim Dim t t as string as string = s= s

Boxing und Unboxing

Jeder Datentyp kann als Objekt gespeichert Jeder Datentyp kann als Objekt gespeichert oder übergeben werdenoder übergeben werden

Dim Dim i i as integer as integer = 123= 123DimDim o o as object as object = i= iDim Dim j j as integer as integer = = Ctype(o, Integer)Ctype(o, Integer)

123123i

o

123123

System.Int32System.Int32 }} ““Boxing”Boxing”

123123j }} ““Unboxing”Unboxing”

.NET Framework

ASPVB Forms MFC & ATL

Windows API

Warum ein Framework?Einheitliches Programmiermodell

System

System.Data System.Xml

System.Web

Globalization

Diagnostics

Configuration

Collections

Resources

Reflection

Net

IO

Threading

Text

ServiceProcess

Security

Design

ADO

SQLTypes

SQL

XPath

XSLT

RuntimeInteropServices

Remoting

Serialization

Serialization

Configuration SessionState

Caching Security

ServicesDescription

Discovery

Protocols

UIHtmlControls

WebControls

System.Drawing

Imaging

Drawing2D

Text

Printing

System.WinForms

Design ComponentModel

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

BasicsImplikationen

Von VB6 zu VB.NET

VB6VB6

Allgm. SprachenAllgm. Sprachen

.NET CLR.NET CLR

.NET Sprachen.NET Sprachen

VB.NETVB.NET

Mit den .NET Sprachen hat das VB-Konzept „gewonnen“

• dot-Syntax

• Einfache Stringbehandlung

• uvm.

Mit VB.NET verliert VB seine Alleinstellungsmerkmale

VB.NETDie 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

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 DoubleGehalt = 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 InheritanceInterface 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 InheritanceKlasse 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 vonZusammenschluss vonDaten und CodeDaten und Code WerttypWerttyp Keine VererbungKeine Vererbung LeichtgewichtigerLeichtgewichtiger

DatencontainerDatencontainer

Ausnahmebehandlung

Try auszuführende AnweisungenCatch e As COMException FehlerbehandlungCatch e As Exception ...Catch When Err.Number = 5 ...Catch ...Finally Abschließende Behandlung, auch ohne FehlerEnd 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

Delegate Empfänger

Delegate

n:1

Empfänger

MulticastDelegate

MulticastDelegate

n:m

Empfänger

Delegate Empfänger1:1

EmpfängerMulticastDelegate

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 SubEnd 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 TextBoxDim 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

<AttributeUsage(AttributeTargets.All)> Public Class AutorAttribute Inherits Attribute

Public name As String Public project As String

Public Sub New(ByVal name As String) Me.name = name End SubEnd Class

<Autor("Westphal", project:="Roadshow")>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 FooSub Baz()

Console.WriteLine("Foo Baz is running on another thread")End Sub

End Class

Sub main()Dim oFoo As FoooFoo = New Foo()

Dim otter As ThreadStart otter = New ThreadStart(AddressOf oFoo.Baz)

Dim oThread As Thread oThread = New Thread(otter)

oThread.StartEnd 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...Uff...

Mehr Informationen

http://www.microsoft.com/net http://msdn.microsoft.com/net http://www.microsoft.com/germany/msdn http://www.dotnetgerman.com/ http://www.dotnetjumpstart.net/ http://www.gotDotNet.com/ 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)

http://www.gotdotnet.com/events/teched/slides/dev300_cdias.ppt Visual Basic .NET: New Programming Model and Language

Enhancements Boost Development Powerhttp://msdn.microsoft.com/msdnmag/issues/01/02/vbnet/vbnet.asp

Visual Studio Enables the Programmable Webhttp://msdn.microsoft.com/vstudio/nextgen/technology/language.asp

Visual Basic .NET Upgrade Roadmaphttp://msdn.microsoft.com/vbasic/technical/upgrade/roadmap.asp

The Transition from Visual Basic 6.0 to Visual Basic .NEThttp://msdn.microsoft.com/vbasic/technical/upgrade/transition/default.asp

10 More Ways to Prepare for VB.NEThttp://www.devx.com/upload/free/features/vbpj/2001/03mar01/bh_0103/bh_0103.asp

Get Your Designs in Gear for VB.NEThttp://www.devx.com/upload/free/features/vbpj/2000/11nov00/pr0011/pr0011.asp

Drill Down on VB.NEThttp://www.devx.com/upload/free/features/vbpj/2001/01feb02/jf0102/jf0102.asp

VB.NET Quellen 2/2

An Introduction to Threading in VB.NETAn Introduction to Threading in VB.NEThttp://www.asptoday.com/content/articles/20010410.asp?WROXEMPTOKEN=934243ZaVjEiid0J0l7LCYvBGK

Object Oriented Features in VB.NETObject Oriented Features in VB.NEThttp://www.asptoday.com/content/articles/20010518.asp?WROXEMPTOKEN=934243ZaVjEiid0J0l7LCYvBGK

VB .NET DelegatesVB .NET Delegateshttp://www.asptoday.com/content/articles/20010619.asp?http://www.asptoday.com/content/articles/20010619.asp?WROXEMPTOKEN=934243ZaVjEiid0J0l7LCYvBGKWROXEMPTOKEN=934243ZaVjEiid0J0l7LCYvBGK

Polymorphism in VB.NETPolymorphism in VB.NEThttp://www.asptoday.com/content/articles/20010627.asp?http://www.asptoday.com/content/articles/20010627.asp?WROXEMPTOKEN=934243ZaVjEiid0J0l7LCYvBGKWROXEMPTOKEN=934243ZaVjEiid0J0l7LCYvBGK

Visual Basic .NET: Tracing, Logging, and Threading Made Easy with .NEVisual Basic .NET: Tracing, Logging, and Threading Made Easy with .NETThttp://msdn.microsoft.com/msdnmag/issues/01/07/vbnet/vbnet.asphttp://msdn.microsoft.com/msdnmag/issues/01/07/vbnet/vbnet.asp

New Features in Visual Basic .NET: Variables, Types, Arrays, and PropertiesNew Features in Visual Basic .NET: Variables, Types, Arrays, and Propertieshttp://msdn.microsoft.com/msdnmag/issues/01/05/Instincts/Instincts0105.asphttp://msdn.microsoft.com/msdnmag/issues/01/05/Instincts/Instincts0105.asp

Exploiting New Language Features in Visual Basic .NET, Part 2Exploiting New Language Features in Visual Basic .NET, Part 2http://msdn.microsoft.com/msdnmag/issues/01/08/Instincts/Instincts0108.asphttp://msdn.microsoft.com/msdnmag/issues/01/08/Instincts/Instincts0108.asp

Visual Basic .NET - 10 More RAD YearVisual Basic .NET - 10 More RAD Yearsshttp://msdn.microsoft.com/msdnnews/2001/may/RAD/RAD.asphttp://msdn.microsoft.com/msdnnews/2001/may/RAD/RAD.asp

Die Qual der Wahl der SpracheDie Qual der Wahl der Sprachehttp://www.microsoft.com/germany/ms/msdnbiblio/kolumne/300401RW.htmhttp://www.microsoft.com/germany/ms/msdnbiblio/kolumne/300401RW.htm

Empower peopleEmpower people

through great through great softwaresoftware

any time, any place,any time, any place,

and on any deviceand on any device

Recommended