2012-08-25 35 views
0

我目前正在使用此合同檢查參數和返回值不爲空。現在,我需要一種方法來檢查,無論交換機需要哪個分支,IEnumerable產生的代碼值都不能有重複。這可能使用代碼合同。我嘗試使用Contract.ForAll但沒有運氣。代碼合同,以防止列表中的重複

internal static IEnumerable<MenuItemAction> GetMenuActions(MenuItem menuItem) 
{ 
    Contract.Requires(menuItem != null); 
    Contract.Ensures(Contract.Result<IEnumerable<MenuItemAction>>() != null); 

    switch (menuItem.Code) 
    { 
     case 0: 
      return new MenuItemAction[3] { 
     new MenuItemAction(){Code = 0, Label = "."}, 
     new MenuItemAction(){Code = 1, Label = ".."}, 
     new MenuItemAction(){Code = 2, Label = "..."} 
    }; 
     case 1: 
      return new MenuItemAction[2] { 
     new MenuItemAction(){Code = 3, Label = "."}, 
     new MenuItemAction(){Code = 4, Label = ".."} 
    }; 
     case 2: 
      return new MenuItemAction[2] { 
     new MenuItemAction(){Code = 5, Label = "."}, 
     new MenuItemAction(){Code = 6, Label = ".."} 
    }; 
     default: return null; 
    } 
} 

回答

2

嘗試

Contract.Ensures(
    Contract.Result<IEnumerable<MenuItemAction>>() != null && 
    Contract.Result<IEnumerable<MenuItemAction>>().Count() == 
     Contract.Result<IEnumerable<MenuItemAction>>() 
      .Select(m => m.Code) 
      .Distinct() 
      .Count() 
); 
+0

感謝您的回覆,但Distinct會從數組中返回不同的元素,並且它可以在除代碼之外的每個字段中包含不同的元素。數組中的元素的代碼屬性必須是唯一的,但不是其他屬性 –

+0

我相應地更改了示例。 –

+0

完美的作品。謝謝! –

1

Contract.ForAll的代碼是什麼?你觀察到了什麼?

雖然你沒有真正要求替代品,但我建議你考慮使用一個set而不是Array。

覆蓋MenuItemAction上的Equals和GetHashCode,並且每次需要一組不同的項目時 - 使用Set集合。

它保證值是唯一的,如果您想知道是否遇到重複項,您只需檢查Add方法的返回值即可。

這一切都取決於你想達到什麼目的?你想確保不同的值,或者你想確保沒有人將相同的值放兩次? (你是否試圖保護內容或使用?)。

無論如何,MenueItem的代碼是否可以在0-4範圍之外?或在其他words-你實際上意味着對方法的情況下,返回null代碼OutOfRange(提示提示:-))

+0

菜單實際上是從一些奇怪的XML但基本上裝我想用合同斷言的是,生成的IEnumerable MenuItemAction元素對於每個值具有不同的Code屬性。我的意思是可以有1,2或任何MenuItemAction對象,但每個人的Code屬性必須有不同的值。 –