c# - 将 switch 语句转换为 switch 表达式

我将 switch 语句转换为表达式并期望 value 具有相同的类型。但是,表达式返回十进制类型而不是 int。

using System;
                    
public class Program
{
    public enum SomeType
    {
        INT32,
        DECIMAL
    }
    
    public static void Main()
    {
        _ = Enum.TryParse("INT32", out SomeType paramType);
        
        object? value = null;
        
        // 
        
        value = paramType switch
        {
                SomeType.DECIMAL => (decimal)2.0,
                SomeType.INT32 => (int)1,
                _ => throw new ArgumentOutOfRangeException($"Not expected type.")
        };
        
        Console.WriteLine(value);
        Console.WriteLine(value.GetType().ToString());
        
        value = null;
        
        switch(paramType)
        {
            case SomeType.DECIMAL:
                value = (decimal)2.0;
                break;
            case SomeType.INT32:
                value = (int)1;
                break;
            default:
                throw new ArgumentOutOfRangeException($"Not expected type.");
        }
        
        Console.WriteLine(value);
        Console.WriteLine(value.GetType().ToString());
    }
}

结果:

1
System.Decimal

1
System.Int32

这是为什么?你可以在这里试试:https://dotnetfiddle.net/

回答1

switch 表达式试图找到“最佳”结果类型,就像隐式类型数组一样。

给定类型 intdecimal,最好的结果类型是 decimal,因为虽然存在从 intdecimal 的隐式转换,但只有从 decimalint 的显式转换(因为它丢失信息)。

switch 表达式会将所选“分支”的结果隐式转换为该类型,而不管它被分配给的变量的类型。

换句话说,您的代码相当于:

object? value = null;

// The compiler selects tmp here based as the best result type
// between int and decimal
decimal tmp = paramType switch { ... };

// Now the assignment performs any conversions required to assign
// to the variable
value = tmp;

如果要使 switch 表达式的结果类型为 object,则需要确保其中一个分支返回 object。例如:

value = paramType switch
{
    SomeType.DECIMAL => (object) 2.0m,
    SomeType.INT32 => 1,
    _ => throw new ArgumentOutOfRangeException($"Not expected type.")
};

(使用 2.0m 只是为了展示一种更好的方式来提出 decimal 而不是投射 double value...)

现在结果类型是 object,在您的示例代码中,您最终会得到一个装箱的 int,而不是在装箱之前将 int value 转换为 decimal

相似文章

html - 对齐拨动开关左侧的标签

我有以下代码,目前标签显示在拨动开关的右侧,我希望将其放在左侧。CSS代码是文件的一部分,理想情况下不应直接修改,而是扩展。谢谢!.switch{/*Finetunetheswitch*/--heig...

随机推荐

最新文章