question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

VB -> C#: Converter ignores the three-valued logic for nullable types and relational operators.

See original GitHub issue

VB.Net input code

Public Sub Main()
    Dim x As Integer? = Nothing
    If x <> 10 Then
        Console.WriteLine("Fail!")
    Else
        Console.WriteLine("Ok!")
    End If
End Sub

This will print OK because: x <> 10 results in Nothing with Boolean? type. Nothing is False so code will execute Else statement.

Erroneous output

public static void Main()
{
    int? x = default;
    if (x != 10 == true) {
        Console.WriteLine("Fail!");
    }
    else {
        Console.WriteLine("Ok!");
    }
}

Here the code will incorrectly print Fail because: x != 10 results in true and true is equal to true.

Expected output

  public static void Main()
  {
      int? x = default;
      if ((x == null ? null : x != 10) == true) {
          Console.WriteLine("Fail!");
      }
      else {
          Console.WriteLine("Ok!");
      }
  }

VB uses three-valued logic for nullable types. Any relational comparison (=, <>, >, >=, <, <=) that involves nullable types results in Boolean?. If lhs or rhs is null then the entire expression will be null. The expected output produces ugly code but I’m not sure if it’s possible to maintain the same logic using something simpler as we need to keep bool? as the result of the comparison. I will take a look if there is something in Microsoft.VisualBasic.dll that could simplify the code.

Comparing Nullable Types

Details

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:9 (9 by maintainers)

github_iconTop GitHub Comments

1reaction
GrahamTheCodercommented, Feb 22, 2022

Yep it definitely needs a bunch more tests than it has! I think in the general case you’d need to expand to x.HasValue ? x != 10 : null for the operator (with some consideration for whether x itself is an expression that shouldn’t be reevaluated). Then within the if statement, add the == true like now. Obviously for a single operator condition you can reduce that down.

For the re-evaluatable expression part, there is some code that can help extract temp variables, but you might be better off trying to use some syntax that introduces a variable in scope along the lines of x is {} xVal ? xVal != 10 : null

So for this case you’d end up with x is {} xVal && xVal != 10 I think…which still isn’t exactly pretty

Note: Because the decompilation doesn’t show a call to the VB library I assumed (there I go again assuming) that there wasn’t one, but there may well be.

Is the problem here only with the <> operator, or other things too?

0reactions
Yozercommented, Feb 24, 2022
Dim a As Boolean?
Dim b As Boolean?
Dim x = Operators.CompareObjectEqual(a, b, False) ' True 
Dim y = Operators.ConditionalCompareObjectEqual(a, b, False) ' True
Dim z = a = b 'Nothing

Nullables are value types so VB will box them before calling the methods: Sharplab.io

Read more comments on GitHub >

github_iconTop Results From Across the Web

An Exhausting List of Differences Between VB.NET & C# | ...
Operator =/<> on strings are not the same (or any relational operators for that matter) 64. Nullable value types use three-valued logic ...
Read more >
c# - Three valued logic with nullable bool?
A Nullable can be assigned the values true false, or null. The ability to assign null to numeric and Boolean types is especially...
Read more >
Bang Bang (!!) to clean up argument null checks. : r/csharp
Anecdotally, I work with TypeScript pretty often, which has a similar system as C#. Its types are compiler tricks, and not enforced at...
Read more >
Conversions - C# language specification
This conversion produces a null reference if the target type is a reference type, or the null value (§8.3.12) of the given nullable...
Read more >
VB -> C#: wrong conversion of linq expression containing ...
VB.Net input code Private Shared Sub LinqWithNullable() Dim a = New List(Of Integer?) From {1, 2, 3, Nothing} Dim result = From x...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found