sbyte []可以神奇地转换为byte [] [英] sbyte[] can be magically cast to byte[]
问题描述
我不确定这是否是.NET错误,但我发现它真的很有趣.
I'm not sure whether this is a .NET bug but I find it really interesting.
按预期,我不能这样做:
As expected, I cannot do this:
sbyte[] sbytes = { 1, 2, 3 };
byte[] bytes = sbytes; // fails: cannot convert source type 'sbyte[]' to taget type 'byte[]'
但是,如果 sbytes
的类型是 object
,则此方法有效:
However, if the type of sbytes
is object
, this works:
object obj = new sbyte[]{ 1, 2, 3 };
byte[] bytes = obj as byte[];
Assert.IsNull(bytes, "WTF??")
注释1 : int []
- uint []
和其他原始类型也会发生相同的问题.
Remark 1: The same issue occurs for int[]
- uint[]
and the other primitive types as well.
注释2 :尽管代码将数组作为 byte []
处理,但调试器失去了焦点并在其中显示?
-s数组.
Remark 2: Though the code handles the array as a byte[]
, the debugger loses the focus and shows ?
-s in the array.
注释3 :这仅适用于数组,不适用于基础类型本身:
Remark 3: This works only for arrays, not for the underlying types themselves:
object sbyteObj = (sbyte)1;
byte byteObj = (byte)sbyteObj; // System.InvalidCastException: Specified cast is not valid.
好的,我当然可以检查这种类型:
Ok, of course I can check the type like this:
if (obj.GetType() == typeof(byte[]))
这是 as
运算符和直接强制转换的预期行为,还是这是.NET错误?
Is this an intended behavior of the as
operator and direct casting, or is this a .NET bug?
推荐答案
不,这不是bug.只是C#语言规则(声称没有可用的转换)和CLR规则(其中有 可用的转换)之间的阻抗不匹配.
No, it's not a bug. It's just an impedance mismatch between the C# language rules (which claim there's no conversion available) and the CLR rules (where the conversion is available).
请注意,编译器确实认为自己最了解:
Note that the compiler really, really thinks it knows best:
byte[] bytes = new byte[10];
// error CS0030: Cannot convert type 'byte[]' to 'sbyte[]'
sbyte[] sbytes = (sbyte[]) bytes;
即使您已经编译了带有警告的代码,它也并没有真正做到上面所说的:
And even when you've got code that compiles with a warning, it doesn't really do what it says:
byte[] bytes = new byte[10];
// warning CS0184: The given expression is never of the provided ('sbyte[]')
if (bytes is sbyte[])
{
Console.WriteLine("Yes");
}
运行该代码,您不得到输出...但是,如果您只是更改 bytes
的编译时类型,它可以 打印是:
Run that code and you don't get output... but if you just change the compile-time type of bytes
, it does print Yes:
object bytes = new byte[10];
// No warning now
if (bytes is sbyte[])
{
Console.WriteLine("Yes"); // This is reached
}
这篇关于sbyte []可以神奇地转换为byte []的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!