简体   繁体   中英

Why is this switch case returning a double even though it is an int?

Given following code:

object value = header.DataContentType switch
{
    DataContentType.DOUBLE => (double)BitConverter.ToDouble(currentValueBytes.ToArray()),
    DataContentType.FLOAT => (float)BitConverter.ToSingle(currentValueBytes.ToArray()),
    DataContentType.BYTE => (byte)contentData[i],
    DataContentType.SHORT => (short)BitConverter.ToInt16(currentValueBytes.ToArray()),
    DataContentType.INTEGER => (int)BitConverter.ToInt32(currentValueBytes.ToArray()),
    DataContentType.LONG => (long)BitConverter.ToInt64(currentValueBytes.ToArray()),
    _ => throw new InvalidDataException("Invalid data type"),
};

Now, in case when header.DataContentType is DataContentType.INTEGER , the value gets assigned as a double to value instead of as an int and (int)value causes an InvalidCastException

If I debug I can clearly see that it steps into the INTEGER case, and if I evaluate BitConverter.ToInt32(currentValueBytes.ToArray()) in the debug console I get an integer returned. However, as soon as the switch case is exited the variable value is of type double.

Further, if I manually do value = BitConverter.ToInt32(currentValueBytes.ToArray()) the variable is of the correct type int . Implying the switch statement has to change the type to double for some weird reason.

I would like the switch case to return whatever type the BitConverter returns. How can I make the BitConverter return the type of the correct BitConverter case?

I'm pretty sure things will work better if every case in a switch expression returns a consistent type. They casts you show are superfluous. Each of those BitConverter calls returns the type you expect.

But, remember, each of those things ends up being boxed as an object at some point in your code. It's probably better if you specify when and how that boxing takes place. Consider something like this instead:

object value = header.DataContentType switch
{
    DataContentType.DOUBLE => (object)BitConverter.ToDouble(currentValueBytes.ToArray()),
    DataContentType.FLOAT => (object)BitConverter.ToSingle(currentValueBytes.ToArray()),
    DataContentType.BYTE => (object)contentData[i],
    DataContentType.SHORT => (object)BitConverter.ToInt16(currentValueBytes.ToArray()),
    DataContentType.INTEGER => (object)BitConverter.ToInt32(currentValueBytes.ToArray()),
    DataContentType.LONG => (object)BitConverter.ToInt64(currentValueBytes.ToArray()),
    _ => throw new InvalidDataException("Invalid data type"),
};

I'm intrigued how you are going to consume value at this point. Unboxing is a delicate operation. The only time I've ever done something like this is upstream of a JSON-ification operation (where the Newtonsoft JSON package if very happy serializing boxed native value types).

Replace the switch expression with an actual switch statement assigning value . A switch expression has a single return type that is the "best" type from all the types of the cases, and you will get a compiler error when there is no "best" type. So every case is converted to that "best" type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM