sbyte 可以神奇地转换为byte

我不确定这是否是一个.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??") 

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

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

截图

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

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

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

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

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

不,这不是一个错误。 这只是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 }