2014-03-06 1 views
2

나는 기존 코드에 Code Contracts을 통합하려고하고 있으며, 지금까지는 그다지 좋은 결과를 얻지 못했습니다.Func에서 코드 계약을 정의합니다.>

[ContractClass(typeof(IFooContract))] 
public interface IFoo 
{ 
    object Bar(); 
} 

[ContractClassFor(typeof(IFoo))] 
public abstract class IFooContract : IFoo 
{ 
    object IFoo.Bar() 
    { 
     Contract.Ensures(Contract.Result<object>() != null); 
     throw new NotImplementedException(); 
    } 
} 

public class DelegatedFoo : IFoo 
{ 
    public DelegatedFoo(Func<object> barImplementation) 
    { 
     Contract.Requires(barImplementation != null); 
     _barImplementation = barImplementation; 
    } 
    private readonly Func<object> _barImplementation; 

    [ContractInvariantMethod] 
    private void ObjectInvariants() 
    { 
     Contract.Invariant(_barImplementation != null); 
    } 

    public object Bar() 
    { 
     //"ensures unproven: Contract.Result<object>() != null" here. 
     return _barImplementation(); 
    } 
} 

정적에게 : 그래도 난에 직면하고 문제는 내가 Func을 <에 구현> 즉, 다음과 같은 클래스의 생성자에 전달되는 인터페이스와 하나의 구현 대표에 계약을 설정 한 것입니다 분석기는 "증명되지 않은 것을 보장합니다 : Contract.Result()! = null"이라는 오류를보고합니다. Func <에서 계약을 정의 할 수 있습니까 (연장 작업 : <>)?

이 것이 최선의 해결책입니까? 그래서

public class DelegatedFoo : IFoo 
{ 
    public DelegatedFoo(Func<object> barImplementation) 
    { 
     Contract.Requires(barImplementation != null); 
     _barImplementation = barImplementation; 
    } 
    private readonly Func<object> _barImplementation; 

    [ContractInvariantMethod] 
    private void ObjectInvariants() 
    { 
     Contract.Invariant(_barImplementation != null); 
    } 

    public object Bar() 
    { 
     var result = _barImplementation(); 
     Contract.Assume(result != null); 
     return result; 
    } 
} 

답변

0

, 당신은 Func<object> 인스턴스의 제어는 전달 항상 것? 그렇다면 Func<object> 매개 변수가 참조하는 모든 함수는 Contract.Ensures(Contract.Result<object>() != null) 사후 조건을 정의해야합니다.

Action 매개 변수가있는 경우에도 마찬가지입니다.

또한 가장 명확하게는 Contract.Assume(result != null)을 사용하지 않을 것입니다. null을 돌려주지 않을 거라 확신합니까? 네가 그렇게한다면 어떻게 될까? 대신 Contract.Assert(result != null)으로 변경해보세요. Func<object> 매개 변수를 제어하고 사후 조건을 사용하는 경우 public object Bar() 메서드에 대한 사후 조건을 지정하고 어설 션 또는 가정의 필요성을 피할 수 있어야합니다.

마지막으로 DelegatedFoo의 생성자에 Contract.Ensures(_barImplementation == barImplementation)을 추가하는 것을 고려해 볼 수 있습니다. 그러나 사후 조건이 정의 된 불변 조건에 포함되는 것으로 가정합니다. 나는 항상 항상 — 명시 적으로하고 싶습니다. 특히 정적 분석기가 걱정되는 곳에서는 특히 그렇습니다.