[c#] 다른 결과를 반환하는 C # 스위치 식

내 프로젝트 중 하나에서 C # 8로 전환했습니다. 그리고 나는 나의 모든 switch진술을 표현 으로 옮겼습니다 . 그러나 나는 내 프로젝트가 다르게 작동하기 시작했고 그것이 switch표현 때문이라는 것을 알았습니다 . 예를 들어이 코드를 얻을 수 있습니다

class Program
{
    public enum DataType
    {
        Single,
        Double,
        UInt16,
        UInt32,
        UInt64,
        Int16,
        Int32,
        Int64,
        Byte
    }

    static void Main(string[] args)
    {
        dynamic value1 = 5;
        dynamic value2 = 6;

        var casted = CastToType(value1, DataType.Int16);
        var casted1 = CastToTypeExpression(value2, DataType.Int16);


        var type = casted.GetType(); // Int16
        var type1 = casted1.GetType(); // Double
        var bytes = BitConverter.GetBytes(casted); // byte arr with 2 el => [5, 0] <- expected behavior 
        var bytes1 = BitConverter.GetBytes(casted1); // byte arr with 8 el => [0, 0, 0, 0, 0, 0, 24, 64]
    }

    public static dynamic CastToType(dynamic value, DataType type)
    {
        switch (type)
        {
            case DataType.Byte:
                return (byte)value;
            case DataType.Double:
                return (double)value;
            case DataType.Int16:
                return (short)value;
            case DataType.Int32:
                return (int)value;
            case DataType.Int64:
                return (long)value;
            case DataType.Single:
                return (float)value;
            case DataType.UInt16:
                return (ushort)value;
            case DataType.UInt32:
                return (uint)value;
            case DataType.UInt64:
                return (ulong)value;
            default: throw new InvalidCastException();
        }
    }

    public static dynamic CastToTypeExpression(dynamic value, DataType type)
    {
        return type switch
        {
            DataType.Byte => (byte)value,
            DataType.Double => (double)value,
            DataType.Int16 => (short)value,
            DataType.Int32 => (int)value,
            DataType.Int64 => (long)value,
            DataType.Single => (float)value,
            DataType.UInt16 => (ushort)value,
            DataType.UInt32 => (uint)value,
            DataType.UInt64 => (ulong)value,
            _ => throw new InvalidCastException(),
        };
    }
}

결과를 주석으로 작성했지만 클래식 스위치를 사용하면 tl; dr가 값을 캐스팅하면 예상되는 유형의 값이 반환되지만 스위치 식을 사용하면 “더블”의 유형이 반환 byte[]됩니다. 값의 바이트

둘의 차이점은 무엇입니까? 내가 무엇을 그리워합니까?



답변

스위치 명세서 양식에서 각 팔은 직접 값을 반환합니다. 실제로 object는 메서드의 반환 형식이므로 숫자 형식에서 직접으로 변환됩니다 .

스위치 형식이 약간 다릅니다. 먼저 스위치 식에서 결과를 추출한 다음 해당 결과를 선언 된 반환 형식으로 변환합니다. 스위치 식의 유형은 무엇입니까? 스위치 식의 팔에있는 개별 식의 모든 유형에서 “최상의”형식입니다.

이러한 모든 유형은 암시 적으로 double(유형 자체 중 하나로) 변환 될 수 있으므로 이것이 가장 좋은 유형입니다. 따라서 스위치 표현 방법은 다음과 같습니다.

public static dynamic CastToTypeExpression(dynamic value, DataType type)
{
    double result = type switch
    {
        DataType.Byte => (byte)value,
        DataType.Double => (double)value,
        DataType.Int16 => (short)value,
        DataType.Int32 => (int)value,
        DataType.Int64 => (long)value,
        DataType.Single => (float)value,
        DataType.UInt16 => (ushort)value,
        DataType.UInt32 => (uint)value,
        DataType.UInt64 => (ulong)value,
        _ => throw new InvalidCastException(),
    };
    return result;
}

암시 적으로 형식화 된 배열을 사용하여 스위치 식을 사용하지 않고이 “최고의 형식”을 볼 수 있습니다.

var array = new[]
{
    (byte) 0, 0.0, (short) 0, 0,
    0L, 0f, (ushort) 0, 0U, 0UL
};

여기서의 유형은 array로 추론됩니다 double[].


답변