생성자에서 [Pure]를 언제 사용합니까?


19

.NET의 코드 계약에 대해 배우고 있으며 순수한 생성자의 아이디어를 이해하려고합니다. 코드 계약의 문서 상태 :

계약 내에서 호출되는 모든 메소드는 순수해야합니다. 즉, 기존 상태를 업데이트해서는 안됩니다. 순수한 메소드는 순수한 메소드에 입력 한 후 작성된 오브젝트를 수정할 수 있습니다.

그리고 PureAttribute설명서는 다음 과 같이 말합니다.

유형 또는 메소드가 순수함을 나타냅니다. 즉, 표시되는 상태를 변경하지 않습니다.

메소드와 관련하여 이러한 문장을 이해하지만 생성자는 어떻습니까? 다음과 같은 클래스가 있다고 가정하십시오.

public class Foo
{
    public int Value { get; set; }

    public Foo(int value) {
        this.Value = value;
    }
}

이 생성자는 분명히 새 Foo객체 의 상태에 영향을 주지만 다른 부작용은 없습니다 (예 : 매개 변수를 조작하거나 순수하지 않은 메소드를 호출하지 않음). 이 후보 [Pure]입니까? [Pure]생성자에 속성을 배치하는 것의 중요성은 무엇이며 내 코드에서 언제해야합니까?

답변:


14

다음과 [Pure]같이 메소드를 장식합니다 .

  • 방법에 부작용이없는 경우 예를 들어, 메소드가 데이터베이스에 액세스하여 데이터베이스를 수정하거나 결과가 데이터베이스에 따라 달라지는 것은 순수하지 않습니다.

  • 그리고 당신은 코드 계약에서 사용할 것으로 예상합니다. 예를 들어, 메소드가 순수 하지만 코드 계약에 사용할 의도가없는 경우 추가 [Pure]하면 아무런 이점이 없으며 코드를 더 빠르게 만들지 않습니다.

생성자에 관한 한 .NET에서는 순수 하다고 가정 하고 명시 적 속성이 필요하지 않은 것으로 보입니다 . 와 같은 .NET Framework 소스의 여러 생성자를 살펴 보았으며 속성 DateTime이 없습니다 [Pure].

나는 이것이 여러 가지 이유로 이루어진다 고 생각합니다.

  • [Pure]계약에서 클래스 / 구조를 사용할 수 있도록 속성이 있는 매개 변수없는 생성자를 작성해야하는 것은 너무 비현실적 일 수 있습니다 .

  • 와 같은 일부 String에는 명시적인 생성자가 없습니다.

  • 생성자는 외부 코드 계약에서도 특별한 대우를받습니다. 예를 들어 예외를 예외로 처리하지 않아야합니다 .

  • [Pure]는 단순히 삶을 단순화하기위한 관습이지만이 속성으로 장식 된 방법이 순수한지 확인하기위한 실제 정적 검사는 없습니다. void DestroyDatabase()순수하게 꾸며져있을 수 있으며 코드 계약에는 아무런 문제가 없습니다.

    현재 순수로 선언 된 메소드가 실제로 순수한지 확인하는 Code Contracts의 구성 요소는 없습니다. 따라서 프로그래머가 [Pure]로 메소드를 장식했다면, 그것은 단지 믿어집니다.

    에서 코드 # 5 계약합니다 : 방법 순도

  • .NET Framework 자체에는 순수하지 않은 생성자가 포함되어 있습니다. 예를 들어 컬렉션반복 할 때 부작용이 있는List<T>(IEnumerable<T> collection) 경우 실제로는 불합리합니다 .

  • 계약은 단순하게 유지됩니다. 와 같은 계약을 쉽게 상상할 수 있으므로 Contract.Requires(!string.IsNullOrEmpty(name))정적 string.IsNullOrEmpty순수 를 선언 해야하는 좋은 이유가 있습니다.

    반면에 StringBuilder문자열을 작성하기 위해 비즈니스 클래스의 인스턴스 메소드를 호출하여 무언가를 확인 해야하는 경우 계약을 오용하는 것일 수 있습니다. StringBuilder.ToString그렇더라도 순수한 것으로 표시되지 않은 이유 는 무엇입니까?


시스템 유형에 대한 많은 코드 계약은 " 정규화 된 이름이"System.Diagnostics.Contracts.Contract ","System.String ","System.IO.Path "또는"System으로 시작하는 모든 메소드를 포함하여 계약 검사기에서 가정합니다. . 유형 " ". 불행히도, .NET 유형을 보는 것이 코드 계약과 관련하여 너무 유용한 지 확실하지 않습니다.
pswg

3
순도는 모든 호출 된 코드도 순수해야하거나 호출자가 "순결하지 않은"것 중 하나입니다. 모든 생성자가 기본적으로 순수하다고 생각하기가 어렵습니다.
Frank Hileman

@ FrankHileman : 나도. 지금은 C # 컴파일러가 없지만 생성자와 [Pure]속성이 없는 클래스를 작성 하고 계약의 다른 곳에서 사용하여 결정적인 답변을 얻는 것으로 충분합니다 .
Arseni Mourzenko

1

이 경우 개체를 구성 할 때까지 개체를 사용할 수 없습니다. 따라서 생성자는 순수합니다. 생성자가 다른 코드를 호출하거나 대리자를 호출하고 다른 코드가 변경 가능한 속성을 수정 한 경우 순수하지 않습니다. 더 안전하려면 속성을 변경하지 않는 것이 좋습니다.


따라서 순수한 생성자는 다른 순수한 조건을 만족하는 한 현재 클래스의 상태를 변경할 수있는 순수한 메소드입니까? BTW,이 클래스 자체가 순수하지 않다는 점을 강조하고 싶기 때문에 속성을 변경할 수 있습니다.
pswg

@pswg : 아마도 Microsoft가 대답해야 할 흥미로운 질문을 만들었습니다. 생성자가 변경 가능한 속성을 수정 한 메서드를 호출했다고 가정합니다. 생성자가 여전히 순수합니까? 수정이 외부 뷰어에게는 "보이지 않는"경우에도 기술적으로는 그렇지 않을 것이라고 생각합니다. 원래 예제에서 호출 된 다른 코드가 없으므로 내가 생각할 수있는 정의에 의해 순수해야합니다.
Frank Hileman

@pswg : 속성 집합도 메서드 호출이라는 점을 제외하면 MSDN 포럼에 문의해야한다고 생각합니다.
Frank Hileman

순도의 중심 아이디어가 메소드가 관찰 가능한 변경을 수행하는지 아닌지, 그런 의미에서 호출자 가 변경을 관찰 할 수없는 한 순수하지 않은 메소드를 호출하는지 여부에 관계없이 여전히 순수한 방법 일 것입니다.
pswg

@pswg : 이것이 추상적 정의입니다. 그러나 이러한 것들에 대한 분석기를 작성했다면 아마도 순수하지 않은 메소드 호출도 호출자를 순수하지 않은 것으로 간주합니다. 구현이 간단합니다. 그렇다면 질문은 생성자에게 일반적인 메소드 호출이거나 분석이 얼마나 깊이 진행되는지입니다.
Frank Hileman
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.