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

2 回答 2

3

尝试

Contract.Ensures(
    Contract.Result<IEnumerable<MenuItemAction>>() != null &&
    Contract.Result<IEnumerable<MenuItemAction>>().Count() == 
        Contract.Result<IEnumerable<MenuItemAction>>()
           .Select(m => m.Code)
           .Distinct()
           .Count()
);
于 2012-08-25T19:37:26.720 回答
1

contract.ForAll 的代码是什么?你观察到了什么?

尽管您实际上并没有要求替代方案,但我建议您考虑使用 set 而不是 Array。

覆盖 MenuItemAction 上的 Equals 和 GetHashCode ,并且每次您想要不同项目的集合时 - 使用 Set 集合。

它保证值是唯一的,如果您想知道是否遇到重复项,您只需检查 Add 方法的返回值。

这一切都归结为您到底想要实现什么?您是要确保不同的值还是要确保没有人两次输入相同的值?(您是要保护内容还是使用?)。

无论如何,MenueItem 的代码是否可以超出 0-4 范围?或者换句话说 - 如果代码是 OutOfRange (提示提示 :-)),您实际上是否意味着该方法返回 null

于 2012-08-25T19:35:46.867 回答