Home > Net >  A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nul
A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nul

Time:01-07

This piece of code is for .net core 6 :

internal static string ConvertValueToString(this object value)
{
    switch (value)
    {
        case bool boolValue:
            return boolValue ? "true" : "false";

        case string stringValue:
            return stringValue;

        default:
            return value?.ToString();
    }
}

I want to use it in .net framework 4.8.
In .net framework 4.8 i have 7 errors like below :

A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable type

Invalid expression term 'bool'

Syntax error, ':' expected

Invalid expression term 'string'

Syntax error, ':' expected

The name 'boolValue' does not exist in the current context

The name 'stringValue' does not exist in the current context

How can i rewrite that method for .net framework 4.8?


I rewrote it like this :

if (value.GetType() == typeof(bool))
{
    bool boolValue = (bool)value;
    return boolValue ? "true" : "false";
}
else if (value.GetType() == typeof(string))
{
    string stringValue = (string)value;
    return stringValue;
}
else
{
    return value?.ToString();
}

Is this correct?


Edit 2 :

//if (value.GetType() == typeof(bool))
if (value is string)
{
    bool boolValue = (bool)value;
    return boolValue ? "true" : "false";
}
//else if (value.GetType() == typeof(string))
else if (value is bool)
{
    string stringValue = (string)value;
    return stringValue;
}
else
{
    return value?.ToString();
}

Is this correct too?

CodePudding user response:

This is possibly the cleanest way to do this at the moment:

internal static string ConvertValueToString(this object value)
{
    if (value is bool boolValue)
    {
        return boolValue ? "true" : "false";
    }
    else if (value is string stringValue)
    {
        return stringValue;
    }
    else
    {
        return value?.ToString();
    }
}

CodePudding user response:

You can use the fully qualified names as cases and get the fully qualified name from the Type of the value.

var typeName = value.GetType().FullName;

switch (typeName)
{
    case "System.Boolean":
        // Do some boolean stuff
    break;
    case "System.String":
        // Do some string stuff
    break;
    default:
       // Unexpected type name
    break;
}

Since these types will never change, it is safe to use the string name for comparison.

CodePudding user response:

Another approach to this is to use a List<(Type type, Delegate convert)> to build your own version of a switch/case statement.

private List<(Type type, Delegate convert)> _register
    = new List<(Type type, Delegate convert)>();

public void Case<T>(Func<T, string> convert)
{
    _register.Add((typeof(T), convert));
}

public string Switch<T>(T value)
{
    Func<T, string> convert =
        _register
            .Where(x => x.type.IsAssignableFrom(typeof(T)))
            .Select(x => (Func<T, string>)x.convert)
            .Append(x => x?.ToString())
            .FirstOrDefault();
    
    return convert(value);
}

This can now be used like this:

Case<bool>(x => x ? "true!" : "false!");
Case<string>(x => $"!{x}!");
Console.WriteLine(Switch(true));
Console.WriteLine(Switch("Hello"));

That code writes out:

true!
!Hello!

CodePudding user response:

A third option is to use some extension methods:

public static class Ex
{
    public static (object value, string output) Case<T>(this object value, Func<T, string> convert)
    {
        return typeof(T).IsAssignableFrom(value.GetType()) ? (value, convert((T)value)) : (value, null);
    }

    public static (object value, string output) Case<T>(this (object value, string output) source, Func<T, string> convert)
    {
        return source.output == null ? source.value.Case<T>(convert) : source;
    }

    public static string Switch(this (object value, string output) source)
    {
        return source.output == null ? source.value?.ToString() : source.output;
    }
}

Now you can write this:

var result1 =
    true
        .Case<bool>(x => x ? "true!" : "false!")
        .Case<string>(x => $"!{x}!")
        .Switch();

var result2 =
    "Hello"
        .Case<bool>(x => x ? "true!" : "false!")
        .Case<string>(x => $"!{x}!")
        .Switch();

Console.WriteLine(result1);
Console.WriteLine(result2);

Again this outputs:

true!
!Hello!
  •  Tags:  
  • Related