C# 代码契约:要求IEnumerable为非空
我有以下代码:C# 代码契约:要求IEnumerable为非空,c#,c#-4.0,code-contracts,C#,C# 4.0,Code Contracts,我有以下代码: public static IEnumerable<long> GetAllCombinations(IEnumerable<long> elements) { Contract.Requires(elements != null); return GetAllCombinations(elements.ToList(), 0); } 静态分析现在告诉我添加另一个先决条件: 联合合同:建议的先决条件: 合同。要求最大值>=0 我不理解这个
public static IEnumerable<long> GetAllCombinations(IEnumerable<long> elements)
{
Contract.Requires(elements != null);
return GetAllCombinations(elements.ToList(), 0);
}
静态分析现在告诉我添加另一个先决条件:
联合合同:建议的先决条件:
合同。要求最大值>=0
我不理解这个建议,因为
a如果我已经确保元素不为null,为什么要检查其计数是否大于或等于零?我的意思是,传递一个非空值就意味着它至少包含零个元素
b根据IEnumerable的建议,我应该如何检查计数或最大值?我看到的唯一方法是将elements.ToList分配给一个额外的变量并检查该变量。但是,如果我不想从IEnumerable中列出一个列表,那又怎么样呢
让我感到困惑
编辑:
我知道IEnumerable的所有扩展方法,并且非常了解.Any、.Count等
让我困惑的是来自静态分析器的消息。有人能解释为什么它声明Contract.Requiresmaximum>=0吗
它是否意味着我认为它意味着检查元素计数>=0
而且,正如在评论中提到的,为什么静态分析器仍然对Contract.requireElements.Any不满意 elements.Count将获取IEnumerable的计数。您仍然需要检查计数,例如,某些方法会在一个空IEnumerable单子上引发异常。elements.count将获取IEnumerable的计数。您仍然需要检查计数,例如,有些方法会在一个空IEnumerable单上抛出异常
我的意思是,传递一个非空值
已经表示它至少包含
零元素
不是。相当多的API返回IEnumerable,但实际上总是返回一些东西——只是空的
我该怎么检查计数
或最大值,如
我可数
这才是真正的问题。可枚举项没有用于此目的的API
我的意思是,传递一个非空值
已经表示它至少包含
零元素
不是。相当多的API返回IEnumerable,但实际上总是返回一些东西——只是空的
我该怎么检查计数
或最大值,如
我可数
这才是真正的问题。可枚举项没有用于此目的的API。我不确定为什么静态分析建议检查集合的计数。如果传递了空集合,则对其求值的代码将不会执行,即foreach语句,这应该是正常的。这可能与集合的计数是有符号类型有关?您可能希望尝试使用Contracts.assumelements.Any或声明计数为非负的语句来满足静态分析器的要求 为了解决第二个问题,有很多方法可以确定IEnumerable结构是否为非空。要列出几个由System.Linq命名空间启用的名称,请执行以下操作: 元素。任意//检查是否存在至少一个元素O1。 elements.Count//Count上的所有元素 elements.Single//如果存在多个元素O1,则引发异常。 elements.First//返回第一个元素,如果为空,则引发异常O1。 以下两种变体相当于元素。Any,其中T是容器中元素的类型: elements.SingleOrDefault!=违约 elements.FirstOrDefault!=违约
我不知道为什么静态分析建议检查收集的数量。如果传递了空集合,则对其求值的代码将不会执行,即foreach语句,这应该是正常的。这可能与集合的计数是有符号类型有关?您可能希望尝试使用Contracts.assumelements.Any或声明计数为非负的语句来满足静态分析器的要求 为了解决第二个问题,有很多方法可以确定IEnumerable结构是否为非空。要列出几个由System.Linq命名空间启用的名称,请执行以下操作: 元素。任意//检查是否存在至少一个元素O1。 elements.Count//Count上的所有元素 elements.Single//如果存在多个元素O1,则引发异常。 elements.First//返回第一个元素,如果为空,则引发异常O1。 以下两种变体相当于元素。Any,其中T是容器中元素的类型: elements.SingleOrDefault!=违约 elements.FirstOrDefault!=违约
请记住,Count最终会覆盖整个IEnumerable,这可能会很昂贵。如果您只想检查IEnumerable是否为空,请使用Any方法。非常正确。我忘记了任何一件事,请记住,Count最终会遍历整个IEnumerable,这可能会很昂贵。如果您只想检查IEnumerable是否为空,请使用Any方法。非常正确。我忘了还有什么空的IEnumerable
零元素?@VVS,是的,可枚举。如果传递的是空元素,它将不包含任何元素。@Gary:是的,我已经知道IEnumerable可以有零个或多个元素。这就是为什么我想知道为什么代码契约要我显式地检查这个条件。再次阅读我的论点。@VVS,很抱歉我回答了这个问题:一个空的IEnumerable仍然有零个元素?@Gary:啊,这更像是一个陈述而不是一个问题。一个空的IEnumerable仍然有零个元素?@VVS,是的,可枚举。empty可能被传递了,但它不包含任何元素。@Gary:是的,我已经知道IEnumerable可以有零个或多个元素。这就是为什么我想知道为什么代码契约要我显式地检查这个条件。再读一遍我的论点。@VVS,很抱歉我回答了这个问题:一个空的IEnumerable仍然有零个元素?@Gary:啊,这更像是一个陈述而不是一个问题。Contract.requireElements.Any;从static analyzer.Contract.requirements.Any给出相同的建议;从static analyzer.elements中给出相同的建议。如果元素为null,则Any将失败。这可能是您的问题。@Aren:我仍然有空值的第一个检查,所以这不是问题所在。静态分析器的启发式分析可能不够聪明,无法链接您的合同。我只是说了一个大家对IEnumerable实现所忽略的共同点。试试合同。要求要素!=null&&elements.Any并查看警告是否消失。我认为您使用的方法是错误的。当codecontracs表示maximum>=0时,它指的是此处不存在的参数。有没有可能CodeContracts提供了从输出到方法的坏“链接”?@Porges:我也开始这么想了。就像静态分析器深入到框架源代码中,并将我指向Enumerable.ToList实现中的某个变量一样。我需要验证今晚.elements.Any是否会在元素为null时失败。这可能是您的问题。@Aren:我仍然有空值的第一个检查,所以这不是问题所在。静态分析器的启发式分析可能不够聪明,无法链接您的合同。我只是说了一个大家对IEnumerable实现所忽略的共同点。试试合同。要求要素!=null&&elements.Any并查看警告是否消失。我认为您使用的方法是错误的。当codecontracs表示maximum>=0时,它指的是此处不存在的参数。有没有可能CodeContracts提供了从输出到方法的坏“链接”?@Porges:我也开始这么想了。就像静态分析器深入到框架源代码中,并将我指向Enumerable.ToList实现中的某个变量一样。今晚我需要核实一下。