Frage

Ich drehe mich nur in dem Fuß und würde gerne wissen, ob es gab tatsächliche Gründe diese Situation möglich zu machen.
Und überhaupt, diese Frage kann für die Bequemlichkeit der zukünftigen Fuß Schützen bleiben.


Angenommen, wir einen Wert in vb.net haben:

Dim i as Integer?

Wir wollen einen Wert zuweisen, auf einer Bedingung basieren, und einen ternären Operator verwenden, weil es so ordentlich ist und Sachen:

i = If(condition(), Nothing, 42)

Das heißt, wenn eine Bedingung true ist, verwendet die NULL-Zulässigkeit, andernfalls wird der Wert.
An welchem ??Punkt das Schießen stattfindet. Ohne ersichtlichen Grund entscheiden VB-Compiler, dass der gemeinsame Basistyp für Nothing und Integer ist Integer, an welcher Stelle es still die Aussage übersetzt:

i = If(condition(), 0, 42)

Wenn Sie jetzt sind dies in C # tun:

i = (condition()) ? null : 42;

Sie würden sofort einen Compiler-Fehler erhalten, dass <null> nicht gut mit int mischt. Welches ist groß, wie mein Fuß gewesen wäre gesünder hatte ich diesmal den C # Weg ging. Und dafür zu kompilieren, müssen Sie explizit schreiben:

i = (condition()) ? null : (int?)42;

Nun, Sie können das gleiche tun in VB und nutzen Sie die richtige null-ness Sie erwarten:

i = If(condition(), Nothing, CType(42, Integer?))

Aber das mit dem Fuß Schuss an erster Stelle erfordert. Es gibt keinen Compiler-Fehler und es gibt keine Warnung. Das ist, mit Explicit On und Strict On.


Also meine Frage ist, warum?
Sollte ich dies als einen Compiler Fehler?
Oder kann jemand erklären, warum die Compiler auf diese Weise verhält?

War es hilfreich?

Lösung

Das ist, weil VB Nothing zu C # 's null nicht direkt entspricht.

Zum Beispiel dieser Code in C # wird nicht kompiliert:

int i = null;

Aber das VB.Net Code funktioniert gut:

Dim i As Integer = Nothing

VB.Net der Nothing ist eigentlich eine bessere Übereinstimmung für C # 's default(T) Ausdruck.

Andere Tipps

Der ternäre Operator kann nur einen Typ zurück.

In C #, versucht er, eine Art auf null und 42, zu wählen. Nun, null keinen Typ, so entscheidet sie, dass der Rückgabetyp des ternären Operator, dass der 42 ist; eine einfache alte int. Dann wirft sie, weil Sie nicht null als plain old int zurückkehren kann. Wenn Sie 42 als int? zwingen, der ternäre Operator wird einen int? zurückzukehren, so null gültigen.

Nun, ich weiß nicht, VB, aber unter Angabe von der MSDN,
Assigning Nothing to a variable sets it to the default value for its declared type.

Welche, da VB bestimmt, dass der ternäre Operator eine int zurückkehren (mit dem gleichen Prozess C # hat), ist Nothing 0. Auch die 42 Nötigung eine int? Umdrehung Nothing in den Standardwert von int? zu sein, die null ist, wie erwartet.

Ich denke hat dies etwas mehr mit IF zu tun, als mit Nichts. Betrachten Sie diesen Code ein:

''#     This raises an exception
Dim x As Integer?
x = If(True, Nothing, Nothing)
MessageBox.Show(x.Value)

''#     As does 
Dim x As Integer?
x = Nothing
MessageBox.Show(x.Value)

''#     Changing one of the truthpart arguments of If is what seems to return the zero.
Dim x As Integer?
x = If(True, Nothing, 5)
MessageBox.Show(x.Value)

Warum es dies ich tut noch nicht wissen, wahrscheinlich eine Frage für das VB-Team. Ich glaube nicht, es hat mit dem Schlüsselwort Nothing oder Nullable zu tun.

Nothing und null ist nicht das Gleiche ... aus dem MSDN:

  

Zuweisen von nichts zu einem variablen Sätzen es auf den Standardwert für seinen deklarierten Typen.

Auch

  

Wenn Sie einen Werttyp in Expression liefern, gibt IsNothing immer False.

Beachten Sie, dass int? ein Nullable Type ist, aber es ist immer noch ein Werttyp, kein Referenztyp.

Versuchen Sie es Einstellung statt DbNull.Value ...

Nothing

In einer Reihe von Fällen Nothing wird auf den Standardwert konvertiert werden. Um die Verwendung Nothing auf die gleiche Weise null verwenden würden Sie es auf den richtigen Nullable Type zu werfen brauchen.

Dim str As String
Dim int As Nullable(Of Integer) ' or use As Integer?
Dim reader As SqlDataReader
Dim colA As Integer = reader.GetOrdinal("colA")
Dim colB As Integer = reader.GetOrdinal("colB")
str = If(reader.IsDBNull(colA), DirectCast(Nothing, String), reader.GetString(colA))
int = If(reader.IsDBNull(colB), DirectCast(Nothing, Nullable(Of Integer)), reader.GetInt32(colB))

Dies geschieht, weil Integer kein Referenztyp ist. ‚Nichts‘ ist nur Arbeit für Referenztypen soll. Für Werttypen Nichts Zuordnung wird automatisch auf den Standardwert umgewandelt, die im Falle eines Integer 0 ist.

Dies ist eigentlich jetzt möglich, in VS2015 (am allerwenigsten) unter Verwendung von New Integer?

Bsp .:

  

Wenn (testInt> 0, testInt, New Integer?), Wo testInt vom Typ Integer ist?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top