문제

코드 계약에서 불변을 입증하려고 노력하고 있으며 정렬 된 문자열 목록의 예를 제시 할 것이라고 생각했습니다. 추가를위한 여분의 공간이있는 배열을 내부적으로 유지합니다. List<T>, 기본적으로. 항목을 추가해야 할 때는 배열 등에 삽입됩니다. 나는 세 가지 불변분이 있다고 생각했습니다.

  • 카운트는 합리적이어야합니다 : 부적절하지 않고 최대 버퍼 크기만큼 큽니다.
  • 버퍼의 사용하지 않은 부분에있는 모든 것은 null이어야합니다.
  • 버퍼의 중고 부분에있는 각 항목은 최소한 이전 항목만큼 "큰"이어야합니다.

이제 저는 이런 방식으로이를 구현하려고 노력했습니다.

[ContractInvariantMethod]
private void ObjectInvariant()
{
    Contract.Invariant(count >= 0 && count <= buffer.Length);
    for (int i = count; i < buffer.Length; i++)
    {
        Contract.Invariant(buffer[i] == null);
    }
    for (int i = 1; i < count; i++)
    {
        Contract.Invariant(string.Compare(buffer[i], buffer[i - 1]) >= 0);
    }
}

안타깝게도, ccrewrite 루프를 엉망으로 만들고 있습니다.

사용자 문서에 따르면이 방법은 일련의 호출이어야한다고합니다. Contract.Invariant. 코드를 이와 같은 것으로 다시 작성해야합니까?

Contract.Invariant(count >= 0 && count <= buffer.Length);
Contract.Invariant(Contract.ForAll
    (count, buffer.Length, i => buffer[i] == null));
Contract.Invariant(Contract.ForAll
    (1, count, i => string.Compare(buffer[i], buffer[i - 1]) >= 0));

작동하지만 다소 추악합니다. (이전 시도보다 훨씬 낫습니다.)

내 기대는 불합리합니까? 내 불변은 비합리적입니까?

(또한 물었다 Code Contracts Forum의 질문. 여기에 관련 답변을 직접 추가하겠습니다.)

도움이 되었습니까?

해결책

(예비) MSDN 페이지에서 계약처럼 보입니다. 그래도 문서는 그 기능에 대해 그다지 명확하지 않습니다.

//untested
Contract.Invariant(Contract.ForAll(count, buffer.Length, i => buffer[i] == null));
Contract.Invariant(Contract.ForAll(1, count, 
    i => string.Compare(buffer[i], buffer[i - 1]) >= 0));

다른 팁

(나는 Henk의 대답을 받아 들일 것입니다. 그러나 이것을 추가 할 가치가 있다고 생각합니다.)

질문은 이제 대답되었습니다 MSDN 포럼, 그리고 상향은 첫 번째 형태입니다 그렇지 않습니다 일할 것으로 예상됩니다. 불변은 정말로 일련의 전화가 필요합니다. Contract.Invariant, 그리고 그게 다야.

이로 인해 정적 검사기가 불변을 이해하고 시행하는 것이 더욱 실현 가능합니다.

이 제한은 단순히 모든 논리를 다른 회원에게 넣음으로써 우회 할 수 있습니다. IsValid 속성, 그런 다음 전화 :

Contract.Invariant(IsValid);

그것은 의심 할 여지없이 정적 검사기를 엉망으로 만들지 만, 어떤 경우에는 유용한 대안이 될 수 있습니다.

디자이너들이 바퀴를 조금 재창조하지 않습니까?

무엇이 잘못되었는지 좋은 늙었습니다

bool Invariant() const; // in C++, mimicking Eiffel

?

이제 C#에서 우리는 const를 가지고 있지 않지만 왜 당신은 단지 Invariant 기능

private bool Invariant()
{
  // All the logic, function returns true if object is valid i.e. function
  // simply will never return false, in the absence of a bug
}
// Good old invariant in C#, no special attributes, just a function

그런 다음 해당 기능 측면에서 코드 계약을 사용합니까?

[ContractInvariantMethod]
private void ObjectInvariant()
{
    Contract.Invariant(Invariant() == true);
}

어쩌면 나는 말도 안되는 글을 쓰고 있지만, 그 경우에도 모든 사람이 나에게 잘못을 말할 때 약간의 교훈적인 가치가있을 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top