c# – 为什么在某些值类型的数组之间进行转换似乎打破了类型安全性?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了c# – 为什么在某些值类型的数组之间进行转换似乎打破了类型安全性?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2186字,纯文字阅读大概需要4分钟。
内容图文
参见英文答案 > Why does my C# array lose type sign information when cast to object? 4个
以下代码:
object array = new int[] {-1};
Console.WriteLine("array is uint[]: {0}", array is uint[]);
Console.WriteLine("array[0]: {0:X}", ((uint[])array)[0]);
打印以下内容,没有任何错误:
array is uint[]: True
array[0]: FFFFFFFF
这似乎是我所特有的,因为它似乎打破了类型安全.执行以下操作也是编译时错误:
int[] array = {-1};
uint[] test = (uint[])array;
这种不一致来自何处?为什么CLR实现这样?
请注意,我不相信这与数组协方差相同.在数组协方差中,允许转换,因为存在隐式引用转换;这不是这里的情况,其中两种类型都是值类型,并且它们之间只有显式的强制转换.
对于数组协方差,运行时还会在某些情况下抛出异常(当赋值没有意义时).在这种情况下,运行时不会抛出异常,即使将test [0]分配给Int32范围之外的值也是如此.
解决方法:
.NET中的数组以一种相当破碎的方式协变.
C#中的数组在.NET中协变的方式的子集中是协变的.它仍然破碎,但它不允许:
uint[] test = (uint[])new int[10]; // Compiler Error CS0030 C#
// doesn't allow this covariance
但这是一个C#规则; .NET允许它,它允许在数组之间进行分配,其中类型是相同大小的整数(有符号或无符号),或者具有相同大小的底层类型的枚举.
当然,.NET和C#都允许您将任何数组转换为对象,并且从对象转换为任何数组类型都是合法的,但在运行时可能会失败.所以uint [] test =(uint [])(object)new int [10];是允许的,因为它类似于以下步骤:
object temp = new int[10]; // normal enough asignmnt.
uint[] test = (uint[])temp; // C# doesn't allow assigning
// int[] to uint[] but temp is
// object so the compiler
// doesn't know that's what
// you are doing, and .NET
// does allow it.
来自评论:
Do you know why the CLR allows this conversion at all? Does it help with CLI compliance maybe (ie. allow languages without unsigned types to treat arrays as signed types)
好吧,在CIL中,对于有符号值和无符号值之间的堆栈值,差异较小.如果使用clt,它将从堆栈中弹出两个值,并将它们作为有符号值进行比较,无论它们是否有符号,而clt.un将它们作为无符号值进行比较,无论它们是否为无符号值.同样
在CIL固有的相同大小的有符号和无符号类型之间可以自由移动.
现在,协方差意味着我们可以分配一个等于或窄于其赋值的值;这就是它包括bivariance(指定更窄的东西). C#不考虑int和uint bivariant;你必须在它们之间明确地进行转换,所以将它们包含在协变赋值中是没有意义的.
内容总结
以上是互联网集市为您收集整理的c# – 为什么在某些值类型的数组之间进行转换似乎打破了类型安全性?全部内容,希望文章能够帮你解决c# – 为什么在某些值类型的数组之间进行转换似乎打破了类型安全性?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。