1

Microsoft의 CodeContracts를 가지고 놀고 있는데 해결할 수없는 문제가 발생했습니다. 두 개의 생성자가있는 클래스가 있습니다.CodeContracts : this() 호출을 사용하여 Ctor에서 fullfill이 필요합니까?

public Foo (public float f) { 
    Contracts.Require(f > 0); 
} 
public Foo (int i) 
    : this ((float)i) 
{} 

예제가 단순화되었습니다. 두 번째 생성자가> 0인지 두 번째 생성자의 f을 확인하는 방법을 모르겠습니다. 계약을 통해이 작업을 수행 할 수 있습니까?

+0

왜 그렇게할까요? this ((float) i)는 이미 f> 0인지 검사합니다. – chiccodoro

답변

2

두 번째 생성자의 본문에 전제 조건을 추가하기 만하면됩니다.

public TestClass(float f) 
{ 
    Contract.Requires(f > 0); 
    throw new Exception("foo"); 
} 
public TestClass(int i): this((float)i) 
{ 
    Contract.Requires(i > 0); 
} 

편집에 위의 코드를 호출보십시오 :

TestClass test2 = new TestClass((int)-1); 

당신은 전제 조건이 일반 예외가 발생하기 전에 발생합니다 것을 볼 수 있습니다.

+0

내가 추가 한 라인은 float 생성자가 이미 호출 된 후에 만 ​​평가됩니다. – chiccodoro

+1

@Chiccodoro : 사실, 아니요. 나는 그것을 테스트했고, 첫 번째 생성자의 몸체에 throw 예외를 넣고 잘못된 입력으로 두 번째 생성자를 호출하면 코드 계약에서 사전 조건을 실패 ("i> 0") 한 다음 throw합니다. 첫 번째 생성자의 예외입니다. – koenmetsu

+0

그래서 "계약"기능은 라이브러리가 아닌 언어 확장 기능입니까? 일반적으로 기본 클래스 생성자는 하위 클래스 생성자보다 * 먼저 * 실행되기 때문입니다. – chiccodoro

1

int를 float로 변환하고 거기에 Contract.Requires를 포함하는 정적 메서드를 추가합니다.

class Foo 
{ 
    public Foo(float f) 
    { 
     Contract.Requires(f > 0); 
    } 
    public Foo(int i) 
     : this(ToFloat(i)) 
    { } 

    private static float ToFloat(int i) 
    { 
     Contract.Requires(i > 0); 
     return i; 
    } 
} 

희망이 있습니다.