Code zur Programmiertechnik in .NET
- Ermitteln von Zeilennummern und Methodennamen
- Verzweigungen beliebigen Typs beim
Select Case
-Block - Methodenaufruf bei Objektinstanzierung
- Bestimmen Anzahl der für ein Ereignis registrierten Ereignisbehandlungsprozeduren
- Behandeln gemeinsamer Ereignisse
- Instanzieren anhand des Klassennamens
- Bedingte Vererbung
Ermitteln von Zeilennummern und Methodennamen
Bereits in früheren Versionen von Visual Basic konnte die Nummer der Zeile, an der ein Laufzeitfehler aufgetreten ist, mit der Funktion Erl
bestimmt werden. Diese Funktion ist nun eine Methode der Klasse Err
und kann weiterhin eingesetzt werden. Die Zeilennummern, die Err.Erl
zurückgibt, müssen manuell im Code angegeben werden:
Mittels MethodBase.GetCurrentMethod().Name
kann der Name der gerade ausgeführten Methode ermittelt werden. Eine weitere Möglichkeit hierzu besteht in der Verwendung der Klasse StackTrace
, mit deren Hilfe auch der Name der aufrufenden Methode und die aktuelle Zeilennummer bestimmt werden können. Damit die Zeilennummer ermittelt werden kann, müssen Debugsymbole (PDB-Dateien) vorliegen. Um das nachstehende Beispiel kompilieren zu können, muß der Namensraum System.Diagnostics
importiert werden:
Verzweigungen beliebigen Typs beim Select Case
-Block
Der Select Case
-Block von Visual Basic .NET ist eingeschränkt, was den Typ des Verzweigungsausdrucks anbelangt. So ist es nicht möglich, anhand eines Verweises zu verzweigen. Betrachten wir im Folgenden das Beispiel der Auswertung, welche Schaltfläche eines ToolBar-Steuerelements angeklickt wurde. In diesem Fall läßt Visual Basic .NET Select Case e.Button
nicht zu. Will man trotzdem nicht auf die gute Lesbarkeit von Select Case
verzichten, so kann man als Ausdruck, nach dem verzweigt wird, True
angeben und die Verzweigungsbedingungen explizit formulieren:
Methodenaufruf bei Objektinstanzierung
In C# und einigen anderen Programmiersprachen besteht die Möglichkeit, in einer Anweisung ein Objekt zu instanzieren und eine seiner Methoden auszuführen. Im Falle von C# wird dazu einfach die Anweisung new SampleClass("George").DoSomething(3)
benötigt. Will man diese Zeile direkt in Visual Basic .NET umsetzen, führt dies zu einem Kompilierungsfehler. Trotzdem gibt es eine interessante Lösung:
Wie dem obenstehenden Listing zu entnehmen ist, machen wir hier Gebrauch vom Schlüsselwort Call
, das dazu verwendet werden kann, eine Methode aufzurufen. Call
ist also keinesfalls nur aus Gründen der Codekompatibilität weiterhin vorhanden, sondern macht gewisse Dinge überhaupt erst möglich.
Bestimmen der Anzahl der für ein Ereignis registrierten Ereignisbehandlungsprozeduren
Folgender Code resultierte auf eine Anfrage in einer Newsgroup, bei der es darum ging, festzustellen, wie viele Ereignisbehandlungsprozeduren für ein bestimmtes Ereignis registriert sind:
Ein Ereignis ist nichts anderes als eine Maske für einen Delegaten: Wenn ein Ereignis deklariert wird, wird ein versteckter Delegattyp erstellt, der Methoden mit der gleichen Signatur wie jene des Ereignisses aufnehmen kann. Weiters wird eine versteckte Variable dieses Typs erstellt, deren Name sich aus dem Namen des Ereignisses mit angehängtem »Event« zusammensetzt. Über diese Variable, in unserem Fall FooEvent
kann eine Liste der Delegate, die dazu hinzugefügt wurden, ermittelt werden.
Behandeln gemeinsamer Ereignisse
Folgender einfacher Code zeigt, wie man gemeinsame Ereignisse behandeln kann. Gemeinsame Ereignisse werden in Visual Basic .NET mit dem Modifizierer Shared
markiert. Gemeinsame Ereignisse sind beispielsweise dann sinnvoll, wenn das Instanzieren von neuen Objekten der Klasse bzw. deren Operationen ein Ereignis auslösen sollen:
Instanzieren anhand des Klassennamens
Es kann vorkommen, daß man ein Formular oder eine beliebige andere Klasse instanzieren will, allerdings lediglich über ihren Namen in Form eines Strings verfügt. In diesem Fall kann die Klasse Activator
mit ihrer Methode CreateInstance
Abhilfe schaffen. Nehmen wir an, der Namensraum der Anwendung sei MyApplication
und der Name der Formularklasse SampleForm
; dann kann ein Formular der Klasse SampleForm
folgendermaßen instanziert werden:
Oben angegebener Code funktioniert allerdings nur, wenn sich die Klasse in der Assembly befindet, die gerade ausgeführt wird. Soll eine Klasse aus einer anderen Assembly geladen werden, dann kann die Methode Activator.CreateInstance(String, String)
benutzt werden, der man den vollständigen Namen der Assembly und den qualifizierten Typnamen übergibt. Ist der vollständige Name der Assembly nicht bekannt, kann folgende Funktion verwendet werden:
Damit obenstehender Code funktioniert, muß der Namensraum System.Reflection
importiert werden. Folgendes Listing zeigt ein Beispiel für die Verwendung der Funktion CreateObject
, in dem ein Button-Steuerelement instanziert und einem Formular hinzugefügt wird:
Bedingte Vererbung
Bedingte Kompilierung ist nichts Außergewöhnliches, trotzdem wird oft vergessen, was damit möglich ist. Beispielsweise kann man dadurch ohne großen Aufwand zwischen unterschiedlichen Implementierungen der Basisklasse einer Klasse wechseln. Das erweist sich bei der Entwicklung von Formularen als nützlich. Die Windows-Forms-Entwurfsumgebung kann nämlich nicht mit Formularen umgehen, die von einer abstrakten Basisklasse erben. In diesem Falle könnte man den Kopf einer Klassendefinition mit und ohne MustInherit
in entsprechende Zweige eines #If…#Then…
packen: