vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
Top-Preis! AP-Access-Tools-CD Volume 1  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   RSS-Feeds  | Newsletter  | Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2017
 
zurück
Rubrik: .NET   |   VB-Versionen: VB200815.05.09
Eigenschaften und Verhalten von 'Nothing'

Im Framework-VB stellt 'Nothing' offenbar einfach einen Speicherbereich dar, in dem alle Bits auf '0' gesetzt sind. Angemessen wäre deshalb die Bezeichnung 'Null', die in der VB-Dokumentation auch gelegentlich benutzt wird (z.B. in Zusammenhang mit der Nullable-Struktur).

Autor:  Manfred BohnBewertung:     [ Jetzt bewerten ]Views:  15.048 

Wohl aus Gründen der Kompatibilität mit früheren VB-Versionen (vgl. unten) ist aber die Bezeichnung 'Nothing' weiterverwendet worden. 'Nothing' enthält Methoden wie 'GetType' oder 'ToString'. Die können aber nicht benutzt werden, weil 'Nothing' in dem Fall als eine nicht vorhandene Referenz behandelt wird. Es kommt deshalb zur 'NullReferenceException'.

1. Nothing' wird - abhängig vom Datentyp der Variable - unterschiedlich verwendet und verarbeitet:
Bei Referenztyp-Variablen dient die Zuweisung von 'Nothing' dem Lösen eines evt. vorhandenen Objektverweises. Beim Vergleich mit dieser Speicherstelle wird geprüft, ob ein Verweis auf ein vorhandenes Objekt besteht.

Bei Variablen eines numerischen Werttyps wird bei Zuweisungen aus diesem Speicherbereich die '0' gelesen und entsprechend konvertiert (z.B. 0&, 0D, 0.0#). Diese Umwandlungen (Anpassung der Anzahl der Null-Bits auf die Länge der Variable) scheinen als Erweiterungskonvertierungen eingerichtet zu sein. Bei Vergleichs-Operationen mit Variablen des Werttyps wird jeweils auf den enthaltenen '0'-Wert geprüft.

Als Werttyp (Null-Wert) wird 'Nothing' wie ein Integer (System.Int32) behandelt (z.B. bei inferentieller Deklaration). Trotzdem kann 'Nothing' auch bei 'Option Explicit On' auf Variable des Typs 'Byte' oder 'Short' direkt zugewiesen werden (keine einschränkende Konvertierung).

Bei der Zuweisung auf eine Variable des Datentyps 'Date' entspricht 'Nothing' dem Initialisierungs-Datum: "01.01.0001 00:00:00". (In der VB-Dokumentation werden Initialisierungswerte als 'Standardwerte' bezeichnet.)

Bei Variablen des Typs 'Char' entspricht 'Nothing' dem ASCII-Code '0', wie er von der Funktion 'Chr' (in Microsoft.Visualbasic.Conversion) beim Parameter '0' geliefert wird. Die Konstante 'vbNullChar' entspricht einer STRING-variable, die dieses Zeichen enthält. Sie ist nicht gleich dem Null-Zeichen.

 
Dim c1, c2 As Char
c1 = Nothing 
c2 = Microsoft.VisualBasic.Chr(0) 
 
If c1.Equals(c2) Then Stop ' wird ausgelöst
 
If c1.Equals(Microsoft.VisualBasic.vbNullChar) Then Stop ' wird nicht ausgelöst
If c1 = Microsoft.VisualBasic.vbNullChar Then Stop ' wird ausgelöst

Bei Zeichenfolgen-Variablen ('String'/Referenztyp mit speziellem Verhalten) kann 'Nothing' die Null-Referenz der String-Variable herbeiführen, es kann aber keine Zeichen in einem String überschreiben und den String auch nicht verkürzen.

Dim str1 As String = Nothing ' Null-Referenz
If str1 = Microsoft.VisualBasic.vbNullChar Then Stop ' wird nicht ausgelöst
If str1 = Microsoft.VisualBasic.vbNullString Then Stop ' wird ausgelöst
 
str1 = "XXX" 
Mid(str1, 2) = Nothing ' Mid-Statement für Zeichenersetzung 
if str1 <> "XXX" then stop ' wird nicht ausgelöst 
 
str1 = cstr(Nothing) ' Null-Referenz

Obwohl 'Nothing' dem Null-Zeichen (ASCII) entspricht, verhält es sich nach der expliziten Umwandlung in einen String nicht wie ein Null-Zeichen, sondern wie ein zeichenloser String.

' wird ausgelöst
If Microsoft.VisualBasic.Chr(0).Equals(Nothing) Then Stop
 
' wird nicht ausgelöst
If CStr(Microsoft.VisualBasic.Chr(0)).Equals(CStr(Nothing)) Then Stop

Übergibt man 'Nothing' als Parameter an eine Funktion, die einen Werttyp erwartet, erhält die Funktion tatsächlich den Wert 0. Bei einem Referenztyp ist es die Null-Referenz. Die vorgegebenen Standardwerte optionaler Parameter werden durch die explizite Übergabe von 'Nothing' ggf. überschrieben. Es kann also einen Unterschied ausmachen, ob man einem optionalen Parameter nichts oder 'Nothing' übergibt.

2. Microsoft.Visualbasic
Die Funktionen in 'Microsoft.Visualbasic' betrachten 'Nothing' eingeschränkter als die Framework-Methoden, nämlich nur als Null-Referenz, aber nicht als Null-Wert.

Die in 'Microsoft.VisualBasic.Information' enthaltene Funktion 'IsNothing' gibt 'true' zurück, wenn eine Variable des Referenztyps keinen Objektverweis enthält - in allen anderen Fällen 'false', d.h. eine Variable des Werttyps, die '0' enthält wird NICHT als 'Nothing' identifiziert.

Dim i As Integer = Nothing ' i = 0%
' wird nicht ausgelöst
If Microsoft.VisualBasic.Information.IsNothing(i) Then Stop
 
' wird ausgelöst
If i = Nothing Then Stop 
 
' wird von der IDE nicht zugelassen (wg. Werttyp)
If i Is Nothing Then Stop

'Nothing' wird von der Funktion 'IsNothing' nicht als 'Null', sondern als Null-Referenz interpretiert. Dies gilt auch für die Funktion 'IsReference'. 'IsNumeric' identifiziert 'Nothing' ebenfalls nicht als einen numerischen Wert.

' wird ausgelöst
If Microsoft.VisualBasic.Information.IsReference(Nothing) Then Stop
 
' wird NICHT ausgelöst
If Microsoft.VisualBasic.Information.IsDBNull(Nothing) Then Stop
 
' wird NICHT ausgelöst
If Microsoft.VisualBasic.Information.IsNumeric(Nothing) Then Stop

Die 'IsNothing'-Methode benötigt bei der Prüfung von Referenz-Variablen meist mehr Rechenzeit als der direkte 'Is Nothing'-Vergleich.

Auch bei Stringvariablen ist zu unterscheiden zwischen Framework-Methoden (Nothing = Null-Referenz) und den Methoden, die in 'Microsoft.Visualbasic' enthalten sind (Nothing = Leerstring). Diese Regel gilt aber nicht für die Funktion 'IsNothing'.

Dim str as string = Nothing
 
' wird ausgelöst
If Microsoft.Visualbasic.Information.IsNothing(str) Then Stop
 
' l = 0, als wäre es ein Leerstring
Dim l As Integer = Microsoft.VisualBasic.Len(str)
 
' l = 0, Nothing -> Nullzeichen
l = Microsoft.VisualBasic.Strings.Asc(Nothing)
 
' Ausnahme, als wäre 'str' ein Leerstring
l = Microsoft.VisualBasic.Strings.Asc(str)
 
' gibt einen Leerstring zurück
Microsoft.VisualBasic.Strings.Trim(Nothing)

Bei String-Operationen muss man vorsichtig sein, weil einige Framework-Methoden (System.String) und Basic-Methoden zwar gleich benannt sind, sich bei 'Nothing' aber unterschiedlich verhalten (z.B. 'Trim', 'Split'). Im Kapitel 'Zeichenfolgenbearbeitung: Zusammenfassung' der VB-Dokumentation sind die Basic-Methoden gelistet.

3. String-Verkettung
Bei String-Verkettungs-Operationen gibt es einen interessanten Effekt:
Der &-Operator erweitert die Operanden zunächst zu Strings, bei 'Nothing' zu Leerstrings. Für den +Operator gilt das nicht. Die IDE identifiziert 'Nothing' in dem Fall nämlich als Null-Wert.

Anders ist es, wenn man 'Nothing' zuerst (per 'CChar') in ein NUL-Zeichen umwandelt. Die Methode 'String.ConCat' akzeptiert auch Object-Parameter und wandelt Null-Referenzen in Leerstrings um.

Dim str3 As String = Nothing ' nicht referenzierte Stringvariable 
str3 = Nothing & Nothing & Nothing ' es entsteht ein Leerstring
If str3 = String.Empty Then Stop ' wird ausgelöst 
str3 = cstr(Nothing) & cstr(Nothing) ' es entsteht ein Leerstring 
If str3 = String.Empty Then Stop ' wird ausgelöst 
str3 = CChar(Nothing) & CChar(Nothing) ' String der Länge 2 / NUL-Zeichen
str3 = CChar(Nothing) + CChar(Nothing) ' String der Länge 2
 
str3 = Nothing
str3 = String.concat(str3, str3, str3) ' es entsteht ein Leerstring
if str3 = String.Empty then stop ' wird ausgelöst

4. Wert-Typ
In Zusammenhang mit Variablen eines Werttyps eingesetzt, verhält 'Nothing' sich wie eine Variable des Wertes '0', die den üblichen (Erweiterungs-) Konvertierungen folgt. Einige Beispiele:

Dim shrt As Short = Nothing \ 2 ' shrt = 0
Dim dbl As Double = Math.Sqrt(Nothing) ' dbl = 0
dbl = 2 / Nothing ' dbl = PositiveInfinity
dbl = Nothing ^ Nothing ' dbl = 1 
 
Dim dec As Decimal = 1D / Nothing ' IDE erkennt Division durch '0'
 
Math.Sign(Nothing) ' = 0 
 
Dim dd As Double = 100.0# / (1.0# / Nothing) ' = 0.0# echter VB-Grusel
 
Const x As Double = Nothing ' Konstante mit dem Wert 0
If x <> Nothing Then Stop ' wird nicht ausgelöst

5. DBNull
Die Singleton-Klasse 'DBNull' wird verwendet, um bei Datenbankabfragen anzuzeigen, dass kein Wert in einer Tabellen-Zelle enthalten ist (=fehlender Wert). Da es sich dabei um eine (nur einmal vorhandene) Objekt-Instanz handelt, ist dieser Wert nie 'Nothing'. Abgefragt, verglichen oder zugewiesen wird er durch die 'ReadOnly'-Eigenschaft 'DBNull.Value'. Auf 'DBNull' kann nichts zugewiesen werden, weil es sich dabei um einen Typ handelt.

In System.Data.DataRow steht die Methode 'IsNull' zur Verfügung, durch die fehlende Werte identifiziert werden können.

Dim dtb As New Data.DataTable
Dim value(0) As Object
Dim Colnam As String = "Spalte"
 
With dtb
  .Columns.Add(Colnam, GetType(String))
 
  .Columns(0).AllowDBNull = True ' Nullwerte zulassen
  ' .Columns(0).DefaultValue = "anything" ' Standardwert definieren
 
  value(0) = System.DBNull.Value
  .Rows.Add(value)
  If .Rows(0).IsNull(Colnam) Then Stop ' wird ausgelöst
  If .Rows(0).Item(Colnam) Is Nothing Then Stop ' wird nicht ausgelöst
  If .Rows(0).Item(0).GetType.Equals(GetType(System.DBNull)) Then Stop
 
  value(0) = Nothing
  .Rows.Add(value)
  If .Rows(1).IsNull(Colnam) Then Stop ' hängt von DefaultValue ab
  If .Rows(1).Item(Colnam) Is Nothing Then Stop ' wird nicht ausgelöst
  If .Rows(1).Item(Colnam).GetType.Equals(GetType(System.DBNull)) Then Stop
End With

Gleichgültig, ob man 'Nothing' oder 'DbNull.value' auf eine Zelle der Datatable (System.Data) zuweist, die Zelle enthält den Typ 'DBNull' - und zwar unabhängig davon, ob der Typ der Spalte als ein Wert- oder als ein Referenztyp eingerichtet worden ist. Ist jedoch ein Standardwert für die Spalte definiert worden, wird bei der Zuweisung von 'Nothing' der Standardwert in die Zelle eingetragen.

6. Was noch?
Auch bei Pointer-Variablen (z.B. 'System.IntPtr') wird 'Nothing' als '0' verarbeitet.

Dim ptr As System.IntPtr = Nothing
If IntPtr.Zero.Equals(ptr) Then Stop ' wird ausgelöst

Die VB-Dokumentation schlägt vor, für die Prüfung, ob einer Pointer-Variable ein Wert ungleich '0' zugewiesen worden ist, statt 'Nothing' 'Zero' zu verwenden! 'Nothing' entspricht nämlich angeblich nicht 'Zero'.

Zuweisungen von Werten oder Referenzen auf 'Nothing' gelten als 'syntaktischer Fehler'.

Der 'CType'-Operator akzeptiert 'Nothing' und gibt 'Nothing' zurück. Die IDE überwacht die Konvertierbarkeit der Datentypen.

Dim x As Drawing.Bitmap = CType(Nothing, Drawing.Bitmap)

Interessant ist auch das Verhalten von Variablen des Typs 'Object', die so flexibel sind, dass sie Null-Referenzen, Referenzen oder Werte beliebiger Art enthalten können. Dabei passen sie sich dem jeweils zugewiesenen Typ an.

Dim obj As Object
If obj Is Nothing Then Stop ' wird ausgelöst
obj = 120 ' Integer-Objekt (Werttyp)
If obj Is Nothing Then Stop ' wird nicht ausgelöst
obj = Nothing ' Null-Referenz 
If obj Is Nothing Then Stop ' wird ausgelöst
obj = New Object ' eine Object-Variable entsteht
If obj Is Nothing Then Stop ' wird nicht ausgelöst
If Microsoft.VisualBasic.IsNothing(obj) Then Stop
 
obj = System.DBNull.Value
If obj Is Nothing Then Stop ' wird nicht ausgelöst

'Structures' sind Werttypen, auch wenn sie Elemente enthalten, die Referenztypen sind. Weist man einer Structure-Variable den Wert 'Nothing' zu, werden alle Member initialisiert - Werttypen = 0, Referenztypen = Null-Referenz.

Public Structure Test
  Dim a As Integer
  Dim b As String
  Dim c As Text.StringBuilder
End Structure
 
Dim stc As Test
 
stc.a = 100
stc.b = "soso"
stc.c = New Text.StringBuilder("jaja")
 
stc = Nothing ' --> a = 0; b,c = Nothing

Selbsterstellte Enumerationen sollten immer einen 0-Wert ('None') enthalten, weil Enumerations-Variable grundsätzlich mit 'Nothing' initialisiert werden. (Näheres dazu: VB-Dokumentation, Abschnitt 'FlagsAttribute-Klasse', Richtlinien).

Eine Array-Variable, die keine Referenz besitzt, wird von 'IsArray' nicht als Array identifiziert. Eine Array-Variable, die nur Null-Referenzen enthält, aber schon:

Dim arr As System.Array = Nothing
' wird nicht ausgelöst
If Microsoft.VisualBasic.Information.IsArray(arr) Then Stop
 
Dim iarr() As Integer
' wird nicht ausgelöst
If Microsoft.VisualBasic.Information.IsArray(iarr) Then Stop
 
Dim sarr(100) As String 'Array mit Null-Referenz-Elementen
' wird ausgelöst
If Microsoft.VisualBasic.Information.IsArray(sarr) Then Stop

7. Was fehlt?
Einiges, z.B. Nullables: Werttypen, die auch 'Nothing' (= kein Wert vorhanden) enthalten können.

In VB ist es möglich Werttypen in einer Nullable-Struktur zu 'kapseln", die zusätzlich notiert, ob ein gültiger Wert oder 'Nothing' zugewiesen worden ist (Eigenschaft: 'HasValue'). Bei diesen Variablen ist kein Standardwert definiert. Die Initialisierung dieser Variablen entspricht zwar 'Nothing', aber die Eigenschaft 'HasValue`= false gesetzt.

Obwohl Sie einer Variablen eines auf NULL festlegbaren Typs 'Nothing' zuweisen können, ist es nicht möglich, diese mittels Gleichheitszeichen auf Nothing zu überprüfen. Der Vergleich mithilfe des Gleichheitszeichens, someVar = Nothing, ergibt immer 'Nothing' (Es handelt sich also nicht um einen boolschen Vergleich, sondern TriState!). Sie können die 'HasValue'-Eigenschaft der Variablen auf 'False' überprüfen oder eine Überprüfung mithilfe des Operators 'Is' oder 'IsNot' vornehmen (VB-Doku).

Collections.BitArray: Bei Zuweisung von 'Nothing' werden nicht die Bits 'false', sondern die Variable erhält die Null-Referenz.

Listen, Steuerelemente, ADO/SQL ....

Hinweis für VB6-Umsteiger:
Wenn Sie sich jetzt wundern, liegen Sie richtig.

In VB6 ist 'Nothing' als ein 'nicht vorhandenes Objekt' implementiert.
'Nothing' dient ausschließlich zur Überprüfung, ob von Referenz-Variablen auf eine Objektinstanz verwiesen wird bzw. zum Löschen des Objekt-Verweises.

In VB6 kann man 'Nothing' nicht auf Werttypen zuweisen. Da 'Nothing' ein Objekt ist, wäre dafür die Verwendung der 'Set'-Anweisung erforderlich und die ist bei Werttypen nicht erlaubt.

Auch der Vergleich einer Variable vom Werttyp mit 'Nothing' ist in VB6 unzulässig. Der Versuch führt zur Meldung "ungültige Verwendung eines Objekts".

Dieses Verhalten ist sinnvoll, weil Werttypen niemals 'Nothing' sein können, da sie immer einen Wert (ggf. den Initialisierungswert) enthalten. Die Gleichsetzung von '0' und 'Nothing' gibt es in VB6 nicht.

Dieser Workshop wurde bereits 15.048 mal aufgerufen.

Über diesen Workshop im Forum diskutieren
Haben Sie Fragen oder Anregungen zu diesem Workshop, können Sie gerne mit anderen darüber in unserem Forum diskutieren.

Aktuelle Diskussion anzeigen (10 Beiträge)

nach obenzurück


Anzeige

Kauftipp Unser Dauerbrenner!Diesen und auch alle anderen Workshops finden Sie auch auf unserer aktuellen vb@rchiv  Vol.6

Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv!
- nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten
- Symbol-Galerie mit mehr als 3.200 Icons im modernen Look
Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m.
 
   

Druckansicht Druckansicht Copyright ©2000-2017 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel