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

Gyö*_*zeg 20 c# arrays bytearray

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

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

sbyte[] sbytes = { 1, 2, 3 };
byte[] bytes = sbytes; // fails: cannot convert source type 'sbyte[]' to taget type 'byte[]'
Run Code Online (Sandbox Code Playgroud)

但是,如果类型sbytesobject,则有效:

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

备注1:同样的问题int[]- uint[]以及其他原始类型也是如此.

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

截图

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

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

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

if (obj.GetType() == typeof(byte[]))
Run Code Online (Sandbox Code Playgroud)

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

Jon*_*eet 26

不,这不是一个错误.这是C#语言规则(这要求有没有可用的转换)和CLR规则(其中之间的转换只是一个阻抗失配可用).

请注意,编译器确实认为它最了解:

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

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

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

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

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