Why does C# throw casting errors when attempting m

2019-06-22 00:02发布

问题:

Consider this static test class:

public static class Test
{
    public static ushort sum(ushort value1, ushort value2)
    {
        return value1 + value2
    }
}

This causes the following compile error, with value1 + value2 underlined in red:

Cannot implicitly convert type 'int' to 'ushort'. An explicit conversion exists (are you missing a cast)?

Why?

回答1:

Like C and C++ before it, integers are implicitly widened when used with many operators. In this case, the result of adding two ushort values together is int.

Update:

More information: http://msdn.microsoft.com/en-us/library/aa691330(v=VS.71).aspx

I believe this was originally added in C/C++ because int was a native integer type (and yes, operations were faster on ints than on shorts on 32-bit architectures). I'm unsure of the full rationale for C#.

It does make you think about overflow/truncation considerations when you cast. Accidental overflow is more likely with the smaller integer types.



回答2:

ushort

The following assignment statement will produce a compilation error, because the arithmetic expression on the right-hand side of the assignment operator evaluates to int by default.

ushort z = x + y;   // Error: conversion from int to ushort

To fix this problem, use a cast:

ushort z = (ushort)(x + y);   // OK: explicit conversion


回答3:

The available addition operators in C# only contemplate int, uint, long and ulong data types so in that case you are implicitly casting two ushort instances to int, then performing the addition and then returning an int that cannot be implicitly cast to ushort.

From the C# 4.0 specification, section 7.8.4 Addition operator, you can check that only the the following integer addition operators are available:

int operator +(int x, int y);
uint operator +(uint x, uint y);
long operator +(long x, long y);
ulong operator +(ulong x, ulong y);

The same section also states:

The operands are converted to the parameter types of the selected operator, and the type of the result is the return type of the operator.

Which explains why that expression results in an int.



回答4:

It is because addition or subtraction of ushorts doesn't necessarily result in a ushort. For example, the result could be < 0, which is not a ushort. So you need to give the compiler the hint to not complain by type casting it. I believe this should work: return (ushort)(value1 + value2);