2011-09-26 32 views
10

Chắc chắn, tôi biết sự khác biệt cơ bản giữa số nguyên chưa ký (uint) và số nguyên đã ký (int).Sử dụng uint hoặc int

Tôi nhận thấy rằng trong các lớp công khai .NET, một thuộc tính được gọi là Length luôn sử dụng các số nguyên đã ký.

Có thể điều này là do số nguyên không dấu không tuân thủ CLS.

Tuy nhiên, ví dụ, trong chức năng tĩnh của tôi:

public static double GetDistributionDispersion(int tokens, int[] positions) 

Tham số tokens và tất cả các yếu tố trong positions không thể là tiêu cực. Nếu nó là tiêu cực, kết quả cuối cùng là vô ích. Vì vậy, nếu tôi sử dụng int cả hai cho tokenspositions, tôi phải kiểm tra các giá trị mỗi khi hàm này được gọi (và trả về giá trị không có ý nghĩa hoặc ném ngoại lệ nếu tìm thấy giá trị âm ???), thật tẻ nhạt.

OK, thì chúng ta nên sử dụng uint cho cả hai tham số. Điều này thực sự có ý nghĩa với tôi.

Tôi nhận thấy, tuy nhiên, như trong nhiều API công khai, chúng hầu như luôn sử dụng int. Điều đó có nghĩa là bên trong việc thực hiện của họ, họ luôn luôn kiểm tra tính tiêu cực của mỗi giá trị (nếu nó được cho là không âm)?

Vì vậy, trong một từ, tôi nên làm gì?

tôi có thể cung cấp hai trường hợp:

  1. Chức năng này sẽ chỉ được gọi bằng bản thân mình trong giải pháp của riêng mình;
  2. Chức năng này sẽ được sử dụng làm thư viện bởi những người khác trong nhóm khác.

Chúng tôi có nên sử dụng các lược đồ khác nhau cho hai trường hợp này không?

Peter

P.S .: Tôi đã làm rất nhiều nghiên cứu, và vẫn còn có lý do để thuyết phục tôi không sử dụng uint :-)

+0

Tôi nghĩ rằng bài đăng này: [Sự khác biệt khi sử dụng int và uint và khi nào sử dụng] [1] http: // stackoverflow.com/questions/3068474/khác biệt-of-sử dụng-int-và-uint-và-khi-to-sử dụng là câu trả lời cho câu hỏi của bạn. – Ankar

+0

@Ankar, tôi đã tìm kiếm trước khi đăng câu hỏi này và tôi cũng đọc bài đăng đó, nhưng nó không cung cấp đủ lý do để thuyết phục tôi không sử dụng 'uint'. –

+0

có thể trùng lặp của [Tôi có nên sử dụng uint trong C# cho các giá trị không được âm?] (Http://stackoverflow.com/questions/2013116/should-i-use-uint-in-c-sharp-for- giá trị không thể phủ định) – nawfal

Trả lời

5

Tôi thấy ba tùy chọn.

Sử dụng uint. Khung không phải vì nó không tuân thủ CLS. Nhưng bạn có phải tuân thủ CLS không?(Ngoài ra còn có một số vấn đề không vui vẻ với số học mà cây trồng lên, nó không phải là thú vị để đúc tất cả các nơi. Tôi có xu hướng void uint vì lý do này).

Sử dụng int nhưng việc sử dụng hợp đồng:

Contract.Requires(tokens >= 0); 
Contract.Requires(Contract.ForAll(positions, position => position >= 0)); 

Làm cho nó rõ ràng nó chính xác những gì bạn yêu cầu.

Tạo một kiểu tùy chỉnh mà gói gọn các yêu cầu:

struct Foo { 
    public readonly int foo; 

    public Foo(int foo) { 
     Contract.Requires(foo >= 0); 
     this.foo = foo; 
    } 

    public static implicit operator int(Foo foo) { 
     return this.foo; 
    } 

    public static explicit operator Foo(int foo) { 
     return new Foo(foo); 
    } 
} 

Sau đó:

public static double GetDistributionDispersion(Foo tokens, Foo[] positions) { } 

Ah, tốt đẹp. Chúng tôi không phải lo lắng về nó trong phương pháp của chúng tôi. Nếu chúng tôi đang nhận được một Foo, nó hợp lệ.

Bạn có lý do yêu cầu không tiêu cực trong miền của mình. Nó mô hình hóa một số khái niệm. Cũng có thể quảng bá khái niệm đó với một đối tượng bonafide trong mô hình miền của bạn và đóng gói tất cả các khái niệm đi kèm với nó.

+0

Có vẻ như Hợp đồng Mã (hoặc Standard hoặc Premium edition) sẽ không hoạt động trên phiên bản VS express :-) –

+0

@Peter Lee: Tôi nghĩ điều đó có thể đúng. Bạn cũng có thể sử dụng mệnh lệnh bảo vệ kiểu cũ. – jason

+0

bạn có nghĩa là một cái gì đó như 'if (tokens <0) ném ArgumentException mới (" mã thông báo không nên là tiêu cực "," thẻ ")'? –

1

int. nó mang lại sự linh hoạt hơn khi bạn cần thực hiện thay đổi API trong tương lai gần. chẳng hạn như chỉ mục tiêu cực thường được sử dụng bởi python để chỉ đếm ngược từ cuối chuỗi.

giá trị cũng chuyển thành âm khi tràn, xác nhận sẽ bắt được.

sự cân bằng giữa tốc độ và độ mạnh mẽ của nó.

+0

Tôi hiểu điểm này khi tôi nhận được thông tin này từ các bài đăng khác. Nhưng sau đó, họ luôn luôn kiểm tra tiêu cực trong việc thực hiện của họ, nếu các giá trị không phải là tiêu cực? –

+0

có họ đã làm. Đó là một sự cân bằng. Nếu bạn không 'như thế này, thuộc tính phương pháp xác nhận của bạn [Có điều kiện ("DEBUG")], nó sẽ chỉ kiểm tra xây dựng gỡ lỗi. BTW, uint không thực hiện bất kỳ ranh giới kiểm tra nào cả trong thời gian chạy trừ khi bạn khai báo yêu cầu kiểm tra một cách rõ ràng. – Bamboo

2

Có cho int. Một lần tôi đã cố gắng để đi uint bản thân mình chỉ để refactor tất cả mọi thứ một lần nữa ngay sau khi tôi đã chia sẻ của tôi gây phiền nhiễu phôi trong lib của tôi. Tôi đoán quyết định truy cập int là vì lý do lịch sử mà thường là kết quả của -1 cho biết một số loại lỗi (ví dụ trong IndexOf).

1

Khi bạn đọc nó vi phạm các quy tắc thông số kỹ thuật chung, nhưng sau đó sẽ được sử dụng như thế nào và trong trường hợp nó sẽ được kết hợp với phương pháp khác bình thường của chúng để họ mong đợi int làm thông số sẽ đưa bạn vào sự cố khi truyền các giá trị.

Nếu bạn chuẩn bị sẵn sàng làm thư viện thì tốt hơn bạn nên tuân thủ các điều kiện khác mà bạn cần phải chú ý đến các điều kiện trong đó bạn có thể không nhận được giá trị tích cực.

Interesting Read - SO link

2

tôi sử dụng uint.

Vâng, câu trả lời khác đều là đúng ... Nhưng tôi thích sau đó uint vì một lý do:

Make giao diện hơn rõ ràng. Nếu một tham số (hoặc một giá trị trả lại) không được ký, đó là vì nó không thể là số âm (bạn đã thấy số đếm tiêu cực chưa?). Nếu không, tôi cần phải kiểm tra các tham số, tham số tài liệu (và giá trị trả về) mà không được âm; sau đó tôi cần phải viết bài kiểm tra đơn vị bổ sung để kiểm tra các thông số và trả về giá trị (wow, và ai đó sẽ khiếu nại cho làm phôi? Là int phôi nên thường xuyên? Không, theo kinh nghiệm của tôi).

Ngoài ra, người dùng được yêu cầu kiểm tra các giá trị trả về tiêu cực, điều này có thể tồi tệ hơn.

Tôi không bận tâm về sự tuân thủ của CLS, vậy tại sao tôi nên như vậy? Theo quan điểm của tôi, câu hỏi cần được đảo ngược: tại sao tôi nên sử dụng int khi giá trị không thể là số âm?

Để trả về giá trị âm cho thông tin bổ sung (lỗi, ví dụ ...): Tôi không thích thiết kế C-ish. Tôi nghĩ rằng có thể có một thiết kế hiện đại hơn để thực hiện điều này (tức là sử dụng Ngoại lệ, hoặc sử dụng thay đổi giá trị ra ngoài và giá trị trả về boolean).

+0

Những gì bạn trả lời chính xác là những gì tôi quan tâm. Có thể sử dụng 'uint' là tốt cho hàm/phương thức sẽ chỉ được sử dụng trong giải pháp của riêng tôi. –

+0

Chắc chắn nó phụ thuộc chủ yếu vào yêu cầu của bạn. Tôi nghĩ rằng CLS tuân thủ là lý do duy nhất đủ để tránh các loại unsigned. – Luca

Các vấn đề liên quan