Vorwort:
Man behalte sich für das nachfolgende Problem den Fall
Folgender Code:
Zeile 3 funktioniert wie man es erwartet. Der Operator CType in Zeile 17 wird aufgerufen, 123 wird als
Zeile 4 funktioniert aufgrund von Fall
Zeile 5 funktioniert aufgrund von Fall
Bisher macht alles Sinn!
Ent-kommentiert man allerdings Zeilen 6 und 13 bis 15, ändert sich die Situation unerwartet:
Zeile 6 funktioniert wie erwartet, weil der Operator CType in Zeile 13 aufgerufen wird.
Aber plötzlich funktioniert Zeile 5, also Fall
Das Problem tritt in Visual Basic 2010 und 2017 auf.
Gibt es dafür einen guten Grund oder handelt es sich um einen Bug im Compiler oder vielleicht sogar ein Problem in der Sprache ansich? Mir fällt zumindest keine Situation ein, in der das Vorhandensein eines Operator CType von String zum anderen Typ irgendwelche Probleme mit den impliziten Konvertierungen machen könnte.
A
hat den Typ Short
. 123S
hat den Typ Short
. (Das Suffix S
steht für "Short".)B
hat den Typ Short
, weil der Compiler den Typ Short
von 123S
übernimmt. (Vorausgesetzt Option Infer On.)C
hat den Typ Integer
. 123
hat den Typ Integer
. (Wenn kein Suffix, wird Integer
angenommen, außer es passt nicht in Integer
sondern nur noch in Long
, dann wird automatisch Long
verwendet.)D
hat den Typ Integer
, weil der Compiler den Typ Integer
von 123
übernimmt.E
hat den Typ Long
. 123L
hat den Typ Long
. (Das Suffix L
steht für "Long".)F
hat den Typ Long
, weil der Compiler den Typ Long
von 123L
übernimmt.G
hat den Typ Integer
. 123S
hat den Typ Short
. Ein Wert vom Typ Short
passt immer ohne Informationsverlust in eine Variable vom Typ Integer
, deshalb erlaubt der Compiler die implizite Konvertierung.H
hat den Typ Integer
. 123L
hat den Typ Long
. Nicht jeder Wert vom Typ Long
passt ohne Informationsverlust in eine Variable vom Typ Integer
, deshalb erlaubt der Compiler im Normalfall keine implizite Konvertierung, aber da es sich um eine Konstante handelt und der Compiler sicherstellen kann, dass dieser Wert vom Typ Long
, nämlich 123L
, auch in Integer
passt, wird die implizite Konvertierung trotzdem erlaubt. Das ist praktisch, wenn man z.B. eine Methode aufrufen will, die Byte
entgegennimmt, dann muss man nicht Foo(CByte(123))
schreiben.Man behalte sich für das nachfolgende Problem den Fall
H
im Hinterkopf.Folgender Code:
VB.NET-Quellcode
- Public Shared Sub Main(Args As String())
- Dim I As Foo
- I = 123
- I = 123S
- I = 123L
- 'I = "123"
- End Sub
- Public Structure Foo
- Public Value As Integer
- 'Public Shared Widening Operator CType(Value As String) As Foo
- ' Return New Foo With {.Value = Integer.Parse(Value)}
- 'End Operator
- Public Shared Widening Operator CType(Value As Integer) As Foo
- Return New Foo With {.Value = Value}
- End Operator
- End Structure
Zeile 3 funktioniert wie man es erwartet. Der Operator CType in Zeile 17 wird aufgerufen, 123 wird als
Integer
übergeben, zurück kommt ein Foo mit Value = 123.Zeile 4 funktioniert aufgrund von Fall
G
oben: Der Operator CType in Zeile 17 nimmt einen Integer
entgegen, Short
passt immer in Integer
, also erlaubt der Compiler die implizite Konvertierung.Zeile 5 funktioniert aufgrund von Fall
H
oben: Long
passt nicht immer in Integer
, aber der Compiler weiß, dass die Konstante 123L
in Integer passt und erlaubt deshalb die implizite Konvertierung.Bisher macht alles Sinn!
Ent-kommentiert man allerdings Zeilen 6 und 13 bis 15, ändert sich die Situation unerwartet:
Zeile 6 funktioniert wie erwartet, weil der Operator CType in Zeile 13 aufgerufen wird.
Aber plötzlich funktioniert Zeile 5, also Fall
H
nicht mehr! Der Wert vom Typ "Long" kann nicht in "Foo" konvertiert werden.
.Das Problem tritt in Visual Basic 2010 und 2017 auf.
Gibt es dafür einen guten Grund oder handelt es sich um einen Bug im Compiler oder vielleicht sogar ein Problem in der Sprache ansich? Mir fällt zumindest keine Situation ein, in der das Vorhandensein eines Operator CType von String zum anderen Typ irgendwelche Probleme mit den impliziten Konvertierungen machen könnte.
"Luckily luh... luckily it wasn't poi-"
-- Brady in Wonderland, 23. Februar 2015, 1:56
Desktop Pinner | ApplicationSettings | OnUtils
-- Brady in Wonderland, 23. Februar 2015, 1:56
Desktop Pinner | ApplicationSettings | OnUtils