如何确保迭代器方法不会产生任何空项?
How can I ensure that an iterator method will not yield any null items?
我想知道是否可以确保(使用 code-contracts)迭代器方法永远不会产生空项。
这个简化的方法:
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 问题,但他们仍然没有修复它,我认为他们不会。
我想知道是否可以确保(使用 code-contracts)迭代器方法永远不会产生空项。
这个简化的方法:
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 问题,但他们仍然没有修复它,我认为他们不会。