In C#, the ability to cast between signed and unsigned integer types appears to be influenced by:
- Whether a scalar or an array type is being converted.
- Whether the variable is declared as an
object
.
Consider the following code example:
// If the variable is declared as a byte array then type casting to sbyte[] results in a
// compile-time error.
byte[] byteArray = new byte[2];
var c = (sbyte[])byteArray; // Compilation eror
// But if the variable is declared as an object then we neither get a compile-time nor a
// run-time error
object byteArrayObject = new byte[2];
var a = (sbyte[])byteArrayObject;
// With an explicitly typed scalar, the byte -> sbyte type conversion succeeds with no errors
byte scalarByte = 255;
var b = (sbyte)scalarByte;
// But if the scalar is declared as an object, an InvalidCastException is thrown at run-time
object byteObject = (byte)4;
var e = (sbyte)byteObject; // InvalidCastException
To summarize:
- Array declared as byte[]: failure
- Array declared as object: success
- Scalar declared as byte: success
- Scalar declared as object: failure
While this example only considers bytes, the same pattern appears to hold true for other integer types. Can anyone explain why these results are so inconsistent?