yaugenka
yaugenka

Reputation: 2861

c# 8.0 switch expression return type and null value

I'm trying to understand how C# 8.0 switch expressions work and have got several questions.

  1. Why is it not possible to use null value in the default case? The compiler throws Cannot convert null to 'int' because it is a non-nullable value type error.
  2. Why is it trying to convert the null value to int whereas the function's return type is 'double?'?

Here is the function I'm playing with:

public static double? SwitchFunction(int x) =>
    x switch
    {
        1 => 1,
        _ => null
    };

Upvotes: 1

Views: 3930

Answers (3)

Peter Huber
Peter Huber

Reputation: 3312

I faced the same problem resulting in a different error message: "No best type was found for the switch expression".

var isRequired = someIntValue switch
    {
      0 => null,
      1 => false,
      2 => true,
      _ => throw new NotSupportedException(),
    };

I couldn't understand this error message until I read the answers here. The compiler cannot figure out what the type of isRequired should be. My intention was bool?. Changing the code to this makes the error message disappear:

var isRequired = someIntValue switch
    {
      0 => (bool?)null,
      1 => false,
      2 => true,
      _ => throw new NotSupportedException(),
    };

On the other hand, I could just tell the compiler what I want:

bool? isRequired = someIntValue switch
    {
      0 => null,
      1 => false,
      2 => true,
      _ => throw new NotSupportedException(),
    };

I read on GitHub that they intend to fix this in a future version.

Upvotes: 0

tmaj
tmaj

Reputation: 35037

You're hitting a problem that is commonly encountered in the conditional expression.

// Compiler Error CS0173
// Type of conditional expression cannot be determined because 
// there is no implicit conversion between 'int' and '<null>'
//
// var d2 = i == 1 ? 1 : null; 

// This works
var d2 = i == 1 ? 1 : (double?) null;

To address the issue in the switch expression you can help the compiler by specifying the type the null is.

int i = 2;
var d = i switch
{
    1 => 1,
    _ => (double?)null
};

Upvotes: 2

Klaycon
Klaycon

Reputation: 11080

In a switch expression, all possible values must be (implicitly castable to) the same type. Because your first case is 1 => 1, and you don't cast the integer literal to a type other than int, the rest of the cases will be assumed to be int as well. You'll need to cast that 1 to (double?) to have the compiler interpret the rest of the cases also as double?, a nullable type - that will solve both of your points.

Upvotes: 7

Related Questions