Code Contract のサンプル InterfaceContracts を眺めてみる

ます、Code Contracts for .NET extension からダウンロード、インストールします。
インストール後、%PROGRAMFILES%\Microsoft\Contracts\Samples に Samples.zip がありますので解凍します。
展開後、幾つかのサンプルがありますが今回は InterfaceContracts を見てみる事にします。


Interface に対して、制約をかけるサンプルの様です。制約は以下の様に指定するようです。

InterfaceContracts の Program.cs をそのまま掲載

using System;
using System.Diagnostics.Contracts;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Contracts.Samples
{
  class Program
  {
    static void Main(string[] args)
    {
      var f1 = new FooImplementation1();
      int r1 = f1.Foo(1);
      Contract.Assert(r1 > 0);

      IFoo f2 = new FooImplementation2();
      int r2 = f2.Foo(1);
    }
  }

  [ContractClass(typeof(IFooContract))]
  interface IFoo
  {
    int Foo(int x);
  }

  [ContractClassFor(typeof(IFoo))]
  class IFooContract : IFoo
  {
    int IFoo.Foo(int x)
    {
      Contract.Requires(x > 0);
      Contract.Ensures(Contract.Result<int>() > 0);

      throw new NotImplementedException();
    }
  }

  public class FooImplementation1 : IFoo
  {
    public int Foo(int x)
    {
      return x;
    }
  }

  public class FooImplementation2 : IFoo
  {
    /// <summary>
    /// Bad implementation of IFoo.Foo which does not always satisfy post condition.
    /// </summary>
    int IFoo.Foo(int x)
    {
      return x - 1;
    }
  }
}

先ず Interface に ContractClass 属性 にて、制約を実装する Class を指定しています。ContractClass 属性で指定した Class では、ContractClassFor 属性 で、Interface を指定します。
この Class で Interface で宣言しているメソッドに対して制約を実装していくようです。
ContractClassFor 属性を指定しなくてもイケそうな気がしたので、属性をつけなかったら、コンパイル時に警告が出ました。

CodeContracts: The interface 'Contracts.Samples.IFoo' specifies the class 'Contracts.Samples.IFooContract' as its contract class, but that class does not point back to this interface.


Code Contracts 中々面白そうです、コンパイル時に警告してくれるので今後流行るのかな?
Code Contracts はここらへんが参考になるのかな。
System.Diagnostics.Contracts Namespace ()


※余談:Groovy でも契約プログラミングって出来るのかな〜?