2015-06-01 36 views

Trả lời

19

Các loại chưa được ký không tuân thủ CLS, do đó Stream.Write không sử dụng uint để bù và đếm.

Xem: uint (C# Reference)

loại Các uint là không CLS-compliant. Sử dụng int bất cứ khi nào có thể.

Có một bài báo cũ: Why we don't have unsigned types in the CLS by Brad Abrams (2 Sep 2003) đó giải thích lý do:

Tuy nhiên có một vấn đề mà tiếp tục trở lên: Tại sao chúng ta không cho phép loại unsigned (UInt32 và những thứ tương tự) trong CLS?

Vâng, thực sự có hai câu trả lời cho câu hỏi này. Ở mức cấp một số ngôn ngữ (chẳng hạn như VB.NET) không cung cấp hỗ trợ đầy đủ cho loại chưa ký. Ví dụ: bạn không thể có các chữ cái chưa ký trong VB.NET…. Nhưng để công bằng, đó không phải là câu trả lời hoàn toàn thỏa mãn vì khi chúng tôi bắt đầu CLS, bạn không thể phân lớp trong VB.NET , nhưng chúng tôi đã mở rộng ngôn ngữ đó để hỗ trợ những gì chúng tôi biết mọi người muốn. Chúng tôi có thể đã làm điều tương tự với các loại unsigned. Nhưng chúng tôi thì không. Tại sao không? Vâng, đó là một lý do sâu sắc hơn. Trong thực tế, cùng một lý do tại sao beta đầu tiên của ngôn ngữ C# không hỗ trợ các loại chưa ký (không có ushort, uint và các loại tương tự).

Cảm giác chung trong số nhiều người trong chúng ta là phần lớn các chương trình được thực hiện với các loại đã ký. Bất cứ khi nào bạn chuyển sang các loại không dấu, bạn buộc phải chuyển đổi mô hình tinh thần (và một diễn viên xấu xí). Trong dàn diễn viên tệ nhất, bạn xây dựng toàn bộ thế giới API song song có các loại chưa ký. Giá trị tránh kiểm tra “< 0” không đáng để bao gồm các generics trong CLS.

(Lưu ý rằng phiên bản mới hơn của VB.Net (VB 8 trở đi) hỗ trợ các loại unsigned).

Một điều nữa (có lẽ không liên quan) thêm, Stream.Write implementation có kiểm tra cho các giá trị tiêu cực:

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

Từ uint MSDN only

Loại uint là không CLS-compliant. Sử dụng int bất cứ khi nào có thể.

Vì vậy, Stream.Write sử dụng int để bù và đếm.

Các reasons given by ShuggyCoUk làm cho nó rõ ràng hơn:

  • uint là không CLS tuân thủ, do đó làm cho tích hợp sẵn trong loại (mảng) phụ thuộc vào nó đã có vấn đề
  • Thời gian chạy như thiết kế ban đầu cấm bất kỳ đối tượng nào trên heap chiếm hơn hơn 2GB bộ nhớ. Vì mảng có kích thước tối đa có thể nhỏ hơn hoặc bằng giới hạn này sẽ là byte mới [int.MaxValue], nó sẽ là gây khó hiểu cho mọi người để có thể tạo ra các mảng có độ dài dương nhưng không hợp pháp .
  • Trước đây C# kế thừa nhiều cú pháp và quy ước của nó từ C và C++. Trong các mảng đó là chỉ đơn giản là số học con trỏ để chỉ mục mảng tiêu cực là có thể (mặc dù thông thường là bất hợp pháp và nguy hiểm). Vì nhiều mã hiện có giả định rằng chỉ số mảng là số âm này có thể là một yếu tố
  • Lưu ý rằng việc sử dụng các số nguyên đã ký cho chỉ mục mảng trong C/C++ có nghĩa là interop với các ngôn ngữ này và chức năng không được quản lý sẽ yêu cầu sử dụng ints trong những trường hợp đó anyway, có thể gây nhầm lẫn do sự không thống nhất.
  • Các BinarySearch thực hiện (một thành phần rất hữu ích của nhiều thuật toán) dựa vào khả năng sử dụng phạm vi tiêu cực của int để chỉ ra rằng giá trị không tìm thấy vị trí mà tại đó một giá trị như vậy nên được chèn vào duy trì sắp xếp.
  • Khi hoạt động trên một mảng, có khả năng bạn sẽ muốn lấy chênh lệch âm của chỉ mục hiện tại. Nếu bạn đã sử dụng khoản chênh lệch sẽ đưa bạn vượt qua phần bắt đầu của mảng bằng cách sử dụng đơn vị thì hành vi quấn quanh sẽ làm cho chỉ mục của bạn có thể hợp pháp (trong đó nó là dương). Với một int kết quả sẽ là bất hợp pháp (nhưng an toàn kể từ khi thời gian chạy sẽ bảo vệ chống lại đọc bộ nhớ không hợp lệ)
Các vấn đề liên quan