为什么Stream.Write不接受UInt?

时间:2015-06-01 18:11:17

标签: c# .net method-signature cls-compliant

Stream.Write使用int而不是UInt对我来说似乎非常不合逻辑...除了"遗产"之外是否有其他解释?这个事实的代码?是否有人想写-1个字节?!?

3 个答案:

答案 0 :(得分:19)

无符号类型不符合CLS,因此Stream.Write不会使用uint进行偏移和计数。

请参阅:uint (C# Reference)

  

uint类型不符合CLS。尽可能使用int。

有一篇旧文章:Why we don't have unsigned types in the CLS by Brad Abrams (2 Sep 2003)解释了原因:

  

然而,有一个问题不断出现:为什么我们不允许   CLS中的无符号类型(UInt32等)?

     

嗯,这个问题确实有两个答案第一个   某些语言(如VB.NET)不提供完全支持   无符号类型。例如,您不能使用无符号文字   VB.NET ...。但公平地说,这不是一个完全令人满意的答案   因为当我们启动CLS时,你无法在VB.NET中进行子类化   或者,但是我们扩展了那种语言来支持我们认识的人   会想要的。我们可以用无符号类型做同样的事情。   但我们没有。为什么不?嗯,这有更深层次的原因。事实上   同样的原因,为什么C#语言的早期测试版不支持   无符号类型(没有ushort,uint等)。

     一般的感觉   我们中的许多人都认为绝大多数编程都已完成   签名类型。无论何时切换到无符号类型,都会强制执行   心理模型切换(和一个丑陋的演员)。在你构建的最糟糕的演员阵容中   采用无符号类型的完整并行API。价值   避免“< 0“检查不值得包含泛型   CLS。

(请注意,较新版本的VB.Net(VB 8以上版本)支持无符号类型)

要添加的另外一件事(可能不相关)Stream.Write implementation会检查负值:

[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"));

答案 1 :(得分:5)

来自uint MSDN only

  

uint类型不符合CLS。尽可能使用int。

所以Stream.Write使用int来表示偏移和计数。

reasons given by ShuggyCoUk更明确:

  
      
  • uint不符合CLS,因此使内置类型(数组)依赖于它会产生问题
  •   
  • 运行时为   最初设计的禁止堆上的任何对象占用更多   超过2GB的内存。由于最大尺寸的数组会小于   或者等于这个限制将是新的字节[int.MaxValue]   令人困惑的是能够产生积极但非法的阵列   长度。      
  •   
  • 历史上C#继承   它的大部分语法和惯例来自C和C ++。在那些阵列中   简单的指针算术,所以负数组索引是可能的   (虽然通常是非法的和危险的)。由于现有的代码很多   假设数组索引是负数,这可能是一个因素
  •   
  • 在相关的说明中,在C / C ++中对数组索引使用有符号整数意味着与这些语言和非托管函数互操作   无论如何都要求在这些情况下使用整数,这可能是   由于不一致而混淆。
  •   
  • BinarySearch实施   (许多算法中非常有用的组件)依赖于能够   使用int的负范围来表示该值不是   找到应插入此类值的位置   保持排序。
  •   
  • 在阵列上操作时,很可能是你   想要对现有指数进行负偏移。如果你用过   一个偏移量,它将使您通过使用单位的数组的开始   那么环绕行为会使你的索引合法化   (因为它是积极的)。使用int,结果将是非法的(但是   安全,因为运行时会防止读取无效的内存)
  •   

答案 2 :(得分:1)

信不信由你,无符号整数是not part of the Common Language Specification (CLS)

MSDN entry for uint

  

uint类型不符合CLS。尽可能使用int。

因此,为了CLS-compliancy的利益,Microsoft在这里使用了int而不是uint