sbyte []可以神奇地转换为byte []

时间:2015-11-24 14:33:01

标签: c# arrays bytearray

我不确定这是否是一个.NET错误,但我发现它真的很有趣。

正如所料,我不能这样做:

sbyte[] sbytes = { 1, 2, 3 };
byte[] bytes = sbytes; // fails: cannot convert source type 'sbyte[]' to taget type 'byte[]'

但是,如果sbytes的类型为object,则可以:

object obj = new sbyte[]{ 1, 2, 3 };
byte[] bytes = obj as byte[];
Assert.IsNull(bytes, "WTF??")

备注1 int[] - uint[]以及其他原始类型也会出现同样的问题。

备注2 :虽然代码将数组处理为byte[],但调试器会失去焦点并在数组中显示? - 。

screenshot

备注3 :这仅适用于数组,不适用于基础类型本身:

object sbyteObj = (sbyte)1;
byte byteObj = (byte)sbyteObj; // System.InvalidCastException: Specified cast is not valid.

好的,我当然可以检查这样的类型:

if (obj.GetType() == typeof(byte[]))

这是as运算符和直接转换的预期行为,还是.NET错误?

1 个答案:

答案 0 :(得分:26)

不,这不是错误。这只是C#语言规则(声称没有转换可用)和CLR规则(转换 可用)之间的阻抗不匹配。

请注意,编译器确实认为它最清楚:

byte[] bytes = new byte[10];
// error CS0030: Cannot convert type 'byte[]' to 'sbyte[]'
sbyte[] sbytes = (sbyte[]) bytes; 

即使你有代码编译警告,它也没有真正按照它所说的那样做:

byte[] bytes = new byte[10];
// warning CS0184: The given expression is never of the provided ('sbyte[]')
if (bytes is sbyte[])
{
    Console.WriteLine("Yes");
}

运行该代码并且获取输出...但如果您只是更改bytes的编译时类型,则 打印是:

object bytes = new byte[10];
// No warning now
if (bytes is sbyte[])
{
    Console.WriteLine("Yes"); // This is reached
}