2010-12-04 1 views
2

를 확인하지 않다고 생각하는 것은 내 코드입니다 "ensures unproven: Contract.ForAll<string>(Contract.Result<IEnumerable<string>>(), s => s != null)"으로 신고되었습니다. 어떻게 그럴 수 있는지 모르겠다 - 그것이 null 항목을 반환하지 않을 것이라는 보장을 생성하고, 분석기는 그것에 대해 불평하지 않는다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?계약은 정적 분석을 잘못 여기 ... 나는이 문제에 대한 몇 시간을 보냈어요 조건을

[편집] 흠 ... 갑자기 나는 Generate 함수에 대한 경고를받습니다. 똑같은, 보장은 입증되지 않았습니다. 나는 이것이 전에는 일어나지 않았다고 맹세할 수 있었지만, 어쨌든 문제는 이제 움직였다. 분석기가 null 항목을 반환 할 방법이 없다는 것을 어떻게 설득 할 수 있습니까? 또는 양자 택일로, 내가 틀렸고 기능은 수 있습니다 null 항목을 반환합니까?

[편집] Blech ... this article은 "사후 조건 (즉, Contract.Ensure)이 정적 검사기에서 지원되지 않습니다."(반복기에서) ... 누구나 확인할 수 있습니까?

+0

Nitpick : 현장에서 사람들이 단어를 사용 "올바른"를위한 분석기의 능력은 결코 사실이 아닌 것으로 진단하지 마십시오. 나는 잠깐이 질문이 매우 재미 있다고 생각했다. 입증되지 않은 것으로 진단 된 실제 재산의 맥락에서, 나는 "부정확하게"대신 사용하는 것이 좋습니다. –

+0

가양 성은 오탐 (false positive)만큼 부정확하다는 의견이 있습니다 :) 두 경우 모두 나는 그 일 때문에 내 일을 할 수 없습니다. –

답변

1

yield return은 현재 컴파일러와 ccrewrite 간의 상호 작용으로 인해 Contract.Ensures과 작동하지 않습니다.

당신이 지금 할 수있는 베스트 계약없이 개인 방법을 작성하는 것입니다 및 공개 방법 다음 Assume 필요한 계약 :

private static IEnumerable<T> RealGenerate<T>(this Func<T> generator) where T : class 
{ 

    if (generator == null) 
    yield break; 

    T t; 
    while ((t = generator()) != null) 
    yield return t; 
} 

public static IEnumerable<T> Generate<T>(this Func<T> generator) where T: class 
{ 
    Contract.Ensures(Contract.Result<IEnumerable<T>>() != null); 
    Contract.Ensures(Contract.ForAll(Contract.Result<IEnumerable<T>>(), item => item != null)); 

    var result = RealGenerate(generator); 
    Contract.Assume(result != null); 
    Contract.Assume(Contract.ForAll(result, item => item != null)); 
    return result; 
} 
+1

흠 ... 나는 틀린 일을해야 할 것입니다. 아직 작동하지 않습니다. "return result"가있는 줄에는 "... 증명되지 않은 것을 보장합니다 ..."라는 전설이 깔려 있습니다. –

+0

죄송합니다. 시간이 없었기 때문에 실제로 코드를 테스트하지 않았지만 이전에이 패턴을 사용했습니다. 컨테이너 분석 (즉, ForAll 및 Exists)도 여전히 "개발 중"이므로 순간적으로 작동하지 않을 수 있습니다. 사실,'IEnumerable '을'T []'또는'List '으로 변경하면 ... 이것이 IEnumerable 등의 게으른 속성과 같은 것으로 생각되기 시작합니다. 일부 enumerables는 한 번 열거 될 수 있습니다 .... 코드 계약 포럼에서이 값을 묻는 것이 좋습니다. – porges

+0

예 ... 필자는 여러 가지 이유로 게으름이 필요했습니다 (텍스트 파일을 읽는 중이고 전체 파일을 메모리에 넣고 싶지는 않습니다 - 각 행을 개별적으로 처리하고 싶습니다) –