Zur Sinnhaftigkeit der Compilerwarnung BC42104 von Visual Basic .NET
Einleitung
Mit Visual Basic 8.0 wurde die neue Compilerwarnung BC42104 (Variable '<variablename>' is used before it has been assigned a value. A null reference exception could result at runtime.) eingeführt. Sie wird ausgelöst, wenn es zu einem lesenden Zugriff auf eine Variable eines Verweistyps mindestens einen Weg im Code gibt, auf dem der Variablen nicht explizit ein Wert zugewiesen wird. Diese Warnung ist aus mehreren Gründen in der Form, wie sie in Visual Basic 8.0 implementiert ist, kontraproduktiv. Einerseits kann ihr Auftreten mit geringem Aufwand vermieden werden, ohne dadurch die Qualität des Quellcodes zu erhöhen. Andererseits tritt die Warnung in Situationen auf, in denen der Zugriff auf eine implizit initialisierte Variable nicht notwendigerweise unbeabsichtigt zu einer NullReferenceException
führt oder der Wert Nothing
sogar erwünscht ist.
Problemfälle
Folgendes Listing zeigt ein Codebeispiel, in dem die Compilerwarnung BC42104 auftritt, da die Variable s
nicht explizit initialisiert wurde und auf ein Instanzmitglied des Objekts, auf das sie verweist, zugegriffen wird. Visual Basic initialisiert Variablen, deren Typ ein Verweistyp ist, automatisch mit dem Wert Nothing
. Die Variable wurde daher implizit initialisiert, obwohl der Beschreibungstext der Warnung gegenteiliges andeutet. Dennoch ist die Warnung in diesem Fall hilfreich, da bei der Ausführung des Codes sicher eine NullReferenceException
auftreten wird.
Die einfachste Möglichkeit, die Warnung für eine Variable zu unterdrücken, besteht darin, die Variable explizit zu initialisieren. Dabei reicht es bereits aus, den Wert der Variablen bei deren Deklaration auf Nothing
festzulegen. Das explizite Initialisieren der Variablen auf Nothing
innerhalb der Variablendeklaration ist jedoch semantisch vollkommen gleichbedeutend mit einer Deklaration ohne explizite Initialisierung der deklarierten Variablen. Durch die explizite Initialisierung der Variablen hat sich an der Wahrscheinlichkeit des Auftretens einer Ausnahme des Typs NullReferenceException
nichts verändert. Es ist lediglich der Code unnötig komplexer und umfangreicher geworden, nicht aber klarer, da die implizite Initialisierung der Variablen auf einen spezifizierten festen Wert in Visual Basic Tradition hat.
Im Wissen um die implizite Initialisierung von Variablen auf Nothing
liegt daher nahe, den Wert der Variablen vor dem Zugriff auf ein Instanzmitglied des Objekts, auf das die Variable verweist, gegen Nothing
zu testen. Zu diesem Zweck können die Operatoren Is
und IsNot
verwendet werden. Das nachstehende Listing zeigt ein Beispiel, in dem eine Variable in Abhängigkeit von einer Bedingung initialisiert wird oder sonst uninitialisiert bleibt. Da die Variable nicht garantiert initialisiert wird, soll vor dem Zugriff auf ein Instanzmitglied überprüft werden, ob die Variable auf ein Objekt verweist. Trotz der Überprüfung des Variablenwertes tritt die Warnung BC42104 auf, und zwar genau in jener Zeile, in welcher der Wert der Variablen mit Nothing
verglichen wird. Beim Vergleich zweier Verweise kann jedoch keine Ausnahme vom Typ NullReferenceException
auftreten. Der Beschreibungstext der Warnung ist wiederum unzutreffend, da Variable '<variablename>' is used before it has been assigned a value nicht aussagt, daß nicht sicher entschieden werden kann, ob die Variable initialisiert wurde oder nicht.
Einen weiteren Problemfall stellt das Auftreten der Compilerwarnung in jenem Szenario dar, in dem der Wert einer nicht explizit initialisierten Variablen einer anderen Variablen zugewiesen wird. Hierbei kann ebenfalls keine NullReferenceException
auftreten, ja, die Zuweisung kann sogar semantisch korrekt sein, selbst wenn die Variable auf der rechten Seite der Zuweisung den Wert Nothing
besitzt.
Weiterhin tritt die Compilerwarnung auf, wenn eine nicht explizit initialisierte Variable an eine Methode übergeben oder einer Eigenschaft zugewiesen wird. Dies ist deshalb problematisch, da einige Methoden durchaus mit übergebenen Verweisen auf Nothing
zurecht kommen oder sogar derartige Verweise in bestimmten Situationen erwarten. Bestes Beispiel dafür ist die Funktion Len
von Visual Basic, welche die Länge der übergebenen Zeichenfolge oder 0, wenn Nothing
übergeben wurde, zurückgibt.
Lösungsansätze
Eine Verbesserung der Situation ist nur durch Ändern der Bedingungen, unter denen die Warnung auftritt, möglich. Das Auftreten der Warnung soll nicht zur Folge haben, daß Entwickler Variablen blindlings explizit auf Nothing
initialisieren, obwohl dies ohnehin bereits implizit vom Compiler vorgenommen werden würde. Vielmehr soll das Auftreten des Compilerfehlers davon unabhängig sein ob die Variable explizit oder implizit auf Nothing
initialisiert wurde. Die im Folgenden angeführten Bedingungen für bzw. gegen das Auftreten der Warnung wurden auf Basis der zuvor gezeigten Problemfälle entwickelt.
Die Compilerwarnung soll dann und nur dann auftreten, wenn
- auf ein Instanzmitglied des Objekts, auf das die Variable verweist, zugegriffen wird, bevor garantiert werden kann, daß ihr Wert ungleich
Nothing
ist.
Dadurch wird verhindert, daß die Warnung auch in Fällen auftritt, in denen sie semantisch keinen Sinn ergibt. Ferner können so Situationen, in denen sicher eine NullReferenceException
zur Laufzeit auftritt, vom Entwickler zur Codierungszeit gezielt entschärft werden.
Sie soll nicht auftreten, wenn eine nicht explizit initialisierte Variable
- mit einer anderen Variablen oder Konstanten mit
Is
oderIsNot
verglichen wird, - an eine Methode übergeben wird oder
- auf der rechten Seite einer Zuweisung steht.
Im ersten der genannten Fälle und bei Zuweisen der Variable an eine Variable oder ein Arrayelement ist das Auftreten einer NullReferenceException
ausgeschlossen. Bei der Übergabe der Variable in einem Methodenparameter oder bei der Zuweisung an eine Eigenschaft ist eine NullReferenceException
zwar nicht ausgeschlossen, in vielen Fällen tritt jedoch keine derartige Ausnahme auf.
Schlußwort
In ihrer aktuellen Form ist die Compilerwarnung BC42104 nur von geringem Nutzen und in vielen Szenarien kontraproduktiv. Deshalb ist es ratsam, die Warnung zu deaktivieren. Dies kann bei Kompilieren mittels vbc.exe
durch Angeben des Warnungscodes 42104 im Wert des Befehlszeilenparameters /nowarn
(-nowarn
) erfolgen. Wird zur Entwicklung Visual Studio 2005 eingesetzt, ist es erforderlich, die Projektdatei (Dateinamenserweiterung .vbproj
) zu bearbeiten und den Warnungscode dem Element NoWarn
hinzuzufügen. Es bleibt zu hoffen, daß sich Microsoft des Problems annimmt und die Warnung entsprechend den in diesem Artikel entwickelten Lösungsansätzen anpaßt oder ersetzt.