如何确保迭代器方法不会产生任何空项?

How can I ensure that an iterator method will not yield any null items?

我想知道是否可以确保(使用 )迭代器方法永远不会产生空项。

这个简化的方法:

public static IEnumerable<object> CreateSomeObjects()
{
    Contract.Ensures(Contract.Result<IEnumerable<object>>() != null);
    Contract.Ensures(Contract.ForAll(Contract.Result<IEnumerable<object>>(), _ => _ != null));

    for (int i = 0; i < 10; ++i)
    {
        yield return new object();
    }
}

导致类似于此的编译时警告:

CodeContracts: MyClass.CreateSomeObjects()[0x9]: ensures unproven: Contract.ForAll(Contract.Result>(), _ => _ != null)

我可以做些什么来向静态检查器证明它?

将契约放在迭代器上的唯一方法是:

public class Graph
{
    public IEnumerable<Node> Nodes(Graph g)
    {
        Contract.Requires(g != null);
        Contract.Ensures(Contract.ForAll(Contract.Result<IEnumerable<Nodei>>, node => node != null));
        foreach (var x in g.MethodForGettingNodes())
        yield return x;
    }
}

上面的约定确保调用者不传入空参数,并且方法本身保证 结果集合中的所有元素都是非空的。

目前,静态检查器不对集合进行推理,因此无法证明 上面的后置条件。

根据文档,自 2009 年以来他们仍然没有修复它,我在 2 年前遇到了 cc 问题,但他们仍然没有修复它,我认为他们不会。