Target type context does not flow into result operands of conditional 'If' expressions
- Dominant language
- No language data
- Stars
- 328
- Forks
- 71
- PR merge metrics
- No merged PRs in 30d
Description
Visual Basic has several "typeless" expressions whose final value depends on target type information:
* The `Nothing` literal
``` VB.NET
Dim ns As String = Nothing
Dim i As Integer = Nothing
Dim ni As Integer? = Nothing
```
* `AddressOf` expressions
``` VB.NET
Dim s As Action(Of String) = AddressOf Console.WriteLine
```
`AddressOf` expressions don't have a type. Target-typing allows overload resolution to pick the correct method and instantiate a delegate referring to that method.
* Lambda expressions
``` VB.NET
Dim f1 = Function() True
Dim f2 As Func(Of Boolean) = Function() True
Dim f3 As Expression(Of Func(Of Boolean)) = Function() True
```
In the code above the same text, `Function() True`, may have an anonymous delegate type ``, named delegate type `Func(Of Boolean)`, or may produce an expression tree based on target type context.
* Array literals
``` VB.NET
Dim arr As Byte() = {1, 2, 3, 4}
```
The code above does not first produce an Integer array then convert it to a Byte array; that's impossible. Instead the array literal is always realized as a Byte array and its elements are each converted to Byte.
``` VB.NET
Dim value = $"Cost {value:C02}"
Dim value
```
* Interpolated string expressions
Because the conditional 'If' operator doesn't propagate target type context into its operands these expressions may be reclassified incorrectly producing programs with subtle bugs or which fail at run-time.
This makes the simple refactoring of an `If` block into an `If` expression dangerous. Additionally, each time we consider adding more target-typed expressions we compound this issue.
Examples of programs failing to compile or compiling with surprising behavior.
``` VB.NET
' Actually assigns False, not null.
Dim trueOrNull As Boolean? = If(False, True, Nothing)
' Fails to infer common type; doesn't compile with Option Strict On.
Dim control As Control = If(isReadOnly, New Label, New TextBox)
control.Text = ...
' Fails to infer common type; doesn't compile at all.
Dim a As Action(Of String) = If(True, AddressOf Debug.WriteLine, AddressOf Trace.WriteLine)
```
Similar "common-type" examples can be made whenever both operands are typeless.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.