带代码契约的迭代器中的错误?

pn.*_*pn. 7 .net c# .net-4.0 code-contracts microsoft-contracts

以下代码在前置条件下失败.这是代码合同中的错误吗?

static class Program
{
    static void Main()
    {
        foreach (var s in Test(3))
        {
            Console.WriteLine(s);
        }
    }

    static IEnumerable<int>Test (int i)
    {
        Contract.Requires(i > 0);
        for (int j = 0; j < i; j++)
            yield return j;
    }
}
Run Code Online (Sandbox Code Playgroud)

Jar*_*Par 2

我的猜测是这与迭代器的延迟性质有关。请记住,合同处理将发生在最终发出的 IL 上,而不是 C# 代码上。这意味着您必须考虑迭代器和 lambda 表达式等功能的生成代码。

如果你反编译该代码,你会发现“i”实际上并不是一个参数。它将是类中用于实现迭代器的变量。所以代码实际上看起来更像下面这样

class IteratorImpl {
  private int i;
  public bool MoveNext() {
    Contract.Require(i >0);
    ..
  }
}
Run Code Online (Sandbox Code Playgroud)

我对合约 API 不是很熟悉,但我的猜测是生成的代码更难验证。