2011-09-26 61 views
10

當然,我知道無符號整數(uint)和有符號整數(int)之間的基本區別。使用uint或int

我注意到在.NET公共類中,名爲Length的屬性始終使用帶符號整數。

也許這是因爲無符號整數不符合CLS。

然而,舉例來說,在我的靜態函數:

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

參數tokenspositions所有元素不能爲負數。如果它是負面的,最終的結果是沒用的。因此,如果我使用tokenspositions這兩者都使用int,則每次調用此函數時都必須檢查這些值(並且如果發現負值,則返回非檢測值或拋出異常???),這很乏味。 OK,那麼我們應該使用uint這兩個參數。這對我來說真的很有意義。

但是,我發現,在許多公共API中,他們幾乎總是使用int。這是否意味着在執行過程中,他們總是檢查每個值的消極性(如果它應該是非負的)?

所以,總之,我該怎麼做?

我公司可提供兩種情況:

  1. 此功能只能由自己在自己的解決方案被稱爲;
  2. 該功能將被其他團隊中的其他人用作圖書館。

我們應該對這兩種情況使用不同的方案嗎?

彼得

P.S:我做了很多的研究,仍然沒有任何理由說服我不要用uint :-)

+0

我認爲這個帖子是:[使用int和uint以及何時使用的區別] [1] http:// stackoverflow。com/questions/3068474 /使用int-and-uint和何時使用差異 是對您的問題的回答。 – Ankar

+0

@Ankar,在發佈這個問題之前我做了一些搜索,我也讀過這篇文章,但沒有提供足夠的理由說服我不要使用uint。 –

+0

可能的重複[我應該使用uint在C#中的值不能爲負?](http://stackoverflow.com/questions/2013116/should-i-use-uint-in-c-sharp-for-值,這是不能被否定的) – nawfal

回答

5

我看到三個選項。

使用uint。該框架並不是因爲它不符合CLS。但是你是否必須符合CLS?(也有一些不太好玩的問題出現在算術中,遍佈各處都不是很有趣,因爲這個原因我傾向於廢止uint)。

使用int但使用合同:

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

讓它明確您需要它到底是什麼。

創建封裝的需求自定義類型:

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); 
    } 
} 

然後:

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

嗯,不錯。我們不用擔心我們的方法。如果我們得到Foo,它是有效的。

你有一個要求在你的域名無負面的理由。這是建模一些概念。不妨將這個概念推廣到你的領域模型中的一個真正的對象,並封裝隨之而來的所有概念。

+0

似乎代碼合同(標準版或高級版)不適用於VS express版:-) –

+0

@Peter Lee:我認爲這也許是對的。你也可以使用老式的守衛子句。 – jason

+0

你的意思是像'如果(令牌<0)拋出新的ArgumentException(「令牌不應該是負面的」,「令牌」)''? –

1

INT。它在不久的將來需要進行API更改時提供更大的靈活性。 如負指數經常被python用來指示從字符串結尾反轉計數。

當溢出時,值也會變爲負值,斷言會抓住它。

其速度與穩健性之間的折衷。

+0

我明白這一點,因爲我從其他職位瞭解到這一點。但是,那麼他們是否總是在執行中做消極檢查,如果這些值不應該是負面的? –

+0

是的,他們做到了。這是一個折衷。如果你不喜歡這個,請聲明斷言方法[Conditional(「DEBUG」)],它只會檢查調試版本。順便說一句,uint在運行時根本不會執行任何檢查邊界,除非明確聲明檢查要求。 – Bamboo

2

是去int。我曾經嘗試過讓自己只在我的腦海裏有一些煩人的演員時重新演繹一切。 我猜是因爲歷史原因決定去int,其中往往-1的結果表示某種錯誤(例如在IndexOf中)。

1

當你閱讀它違反了通用語言規範的規則,但然後多久使用一次該功能,以防萬一它將被其他方法使用,其正常的預期爲int作爲參數將使你進入鑄造價值的麻煩。

如果你打算把它作爲一個庫來使用,那麼它更好地堅持傳統的int,否則你需要隱式地處理其中你可能得不到正值的情況,這意味着亂丟頁面上的檢查。

Interesting Read - SO link

2

我用UINT

是的,其他的答案是正確的......但我更喜歡再UINT爲一個原因:

製作界面更加清晰。如果一個參數(或一個返回的值)是無符號的,那是因爲它不能是負數(你是否看到負數的收集數?)。否則,我需要檢查參數,文檔參數(和返回值),不能爲負數;那麼我需要編寫額外的單元測試來檢查參數和返回的值(哇,並且有人會抱怨做演員?是否int演員如此頻繁?根據我的經驗)。

此外,用戶需要測試返回值的否定性,這可能會更糟。

我不介意CLS compliace,所以我應該怎麼做?從我的角度來看,這個問題應該顛倒過來:當價值不能爲負時,爲什麼我應該使用整數?

對於返回負值的附加信息點(例如錯誤,...):我不喜歡C-ish設計。我認爲可能有更現代的設計來完成這個任務(即使用異常,或者交替使用out值和boolean返回值)。

+0

你的回答正是我所關心的。也許使用'uint'對於只能在我自己的解決方案中使用的函數/方法是很好的。 –

+0

明確地說,它主要取決於您的要求。我認爲符合CLS是避免無符號類型的唯一充分理由。 – Luca

相關問題