Leo*_*rdo 12 .net c# method-signature cls-compliant
Stream.Write使用的对我来说似乎非常不合逻辑int,而不是UInt......对于这个事实,除了"遗留"代码之外是否有其他解释?有人想写-1字节吗?!?
Hab*_*bib 19
无符号类型不符合CLS,因此Stream.Write 不uint用于偏移和计数.
请参阅:uint(C#参考)
uint类型不符合CLS.尽可能使用int.
有一篇旧文章:为什么我们在CLS中没有未签名类型的Brad Abrams(2003年9月2日)解释了原因:
然而,有一个问题不断出现:为什么我们不允许在CLS中使用无符号类型(UInt32等)?
嗯,这个问题确实有两个答案. 在第一级,某些语言(例如VB.NET)不提供对无符号类型的完全支持. 例如,你不能在VB.NET中使用无符号文字.... 但公平地说,这不是一个完全令人满意的答案,因为当我们开始使用CLS时,你也无法在VB.NET中进行子类化,但我们扩展了该语言以支持我们所知道的人们想要的东西.我们可以用无符号类型做同样的事情.但我们没有.为什么不?嗯,这有更深层次的原因.实际上,与C#语言的早期测试版不支持无符号类型(没有ushort,uint等)的原因相同.
我们许多人的普遍感觉是,绝大多数编程都是使用签名类型完成的.无论何时切换到无符号类型,都会强制进行心理模型切换(以及丑陋的转换). 在最糟糕的演员阵容中,您构建了一个完全并行的API世界,它采用无符号类型.避免"<0"检查的价值不值得在CLS中包含泛型.
(请注意,较新版本的VB.Net(VB 8以上版本)支持无符号类型).
还有一件事(可能是不相关的),Stream.Write实现检查负值:
[System.Security.SecuritySafeCritical] // auto-generated
public override void Write(byte[] array, int offset, int count) {
if (array==null)
throw new ArgumentNullException("array", Environment.GetResourceString("ArgumentNull_Buffer"));
if (offset < 0)
throw new ArgumentOutOfRangeException("offset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (count < 0)
throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
if (array.Length - offset < count)
throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOffLen"));
Run Code Online (Sandbox Code Playgroud)
uint类型不符合CLS.尽可能使用int.
因此Stream.Write使用int进行偏移和计数.
ShuggyCoUk给出的理由更清楚:
- uint不符合CLS,因此使内置类型(数组)依赖于它会产生问题
- 最初设计的运行时禁止堆上的任何对象占用超过2GB的内存.由于小于或等于此限制的最大大小的数组将是新的字节[int.MaxValue],因此人们能够生成正但非法的数组长度将是令人费解的.
- 从历史上看,C#从C和C++继承了它的大部分语法和约定.在那些数组中只是指针算术,因此负数组索引是可能的(尽管通常是非法的和危险的).由于现有的许多代码都假设数组索引为负数,因此这将是一个因素
- 在相关的注释中,在C/C++中对数组索引使用有符号整数意味着与这些语言和非托管函数互操作将需要在这些情况下使用整数,这可能由于不一致而混淆.
- BinarySearch实现(许多算法中非常有用的组件)依赖于能够使用int的负范围来指示未找到该值以及应该插入此类值以保持排序的位置.
- 在数组上操作时,您可能希望对现有索引进行负偏移.如果你使用了一个偏移量,它将使你超过使用单位的数组的开始,那么环绕行为将使你的索引可能合法(因为它是正的).使用int结果将是非法的(但是安全,因为运行时将防止读取无效的内存)