2015-01-05 2 views
2

이라는 생성자가있는 MyValue 클래스가 있다고 가정 해 보겠습니다. 그것은 일반적인 목적의 클래스이며, 나는 그것의 생성자에 int 값을 넣을 수 있습니다. 그러나 때로는 더 많은 제약이있는이 클래스를 사용해야합니다. 예를 들어 사용자가 양수 값만 입력하도록 강제해야합니다. MyValue에서 상속받은 새로운 클래스를 만들 수 있지만 구조체에서는 불가능합니다.생성 제한이있는 사용자 정의 클래스

아마 속성을 사용하여이 동작을 수행 할 수 있습니까?

// pseudo code 
[Constraint(Min=0)] 
public MyValue MyProperty { get; set; } 

그리고 MyProperty 어떻게 든이 속성을 읽고, 유효한 값을 확인하는 생성자에서이 제약 조건을 사용할 수 있습니다. 그러나 나는 그것이 불가능하다고 생각한다.

비슷한 문제를 해결하기위한 조언을 해 줄 수 있습니까?

편집 : PostSharp에서이 기능을 사용하는 것처럼 보입니다. http://www.postsharp.net/model/code-contracts 속성은 [EmailAddress]와 같은 속성으로 꾸며졌으며 입력 값을 확인하는 설정기에 생각하는 IL 코드를 삽입합니다. 처음부터 구현하기가 어렵습니까?

+1

생성자 만 체크인 하시겠습니까? –

+0

어디서든 상관 없습니다. 하나의 클래스를 만들고 코드에 제약 조건을 쉽게 추가해야합니다. – zgnilec

+1

"중요하지 않습니다"는 항상 가장 어려운 요구 사항입니다. –

답변

3

방법,

public class MyValue<T> 
{ 
    private T value; 
    private readonly Func<T, bool>[] contraints; 

    public MyValue(
      T value, 
      params Func<T, bool>[] contraints) 
    { 
     this.value = value; 
     this.constraints = constraints; 
     this.Validate(); 
    } 

    public T Value 
    { 
     get 
     { 
      return this.value; 
     } 

     set 
     { 
      this.value = value; 
      this.Validate(); 
     } 
    } 

    private Validate() 
    { 
     if (!this.constriants.All(c => c(this.value)) 
     { 
      // throw some exception. 
     } 
    } 
} 

그래서이 같은 사용에 대한

var myValue = new MyValue(1, value => value >= 0); 

즉 초기 값은 1이며, 값은 항상 0보다 크거나 같아야합니다.


또는 원하는 경우 두 번째 매개 변수 대신 생성자에서 사용자 지정 특성을 읽을 수 있습니다.

가장 신속하게 공용 인터페이스에서 CLSCompliant가 아니더라도 int 대신 uint을 사용하는 것이 좋습니다.

+0

나쁘지는 않지만 새로운 클래스를 만드는 것이 더 좋으며 MyClass에서 상속 받고 construcotr에 제약 조건을 추가하십시오. 나는 더 많은 AOP 스타일이 필요하다. – zgnilec

+0

@zgnilec 이것은 추상 클래스 일 수 있습니다. – Jodrell

1

자동 속성을 사용하지 마십시오. 당신이 많은 유사한 제약 조건이있는 경우

MyValue _myProperty; 
public MyValue MyProperty 
{ 
    get { return _myProperty; } 
    set 
    { 
     // check constraints in setter 
     if(value != null && ...) 
      ... // do something 
     _myProperty = value; 
    } 
} 

, 그것은 코드를 더 건조하게 (MyValue를 구성하는 다른 생성자 오버로드를 매개 변수로 제약을 통과 할 때, 예에) 의미가 유사하여 처리 할 수 ​​있습니다. 오버로딩 비교와 유형 MyValue의 상수를 사용하는 것이 다른 해결책이며, 더 많아야합니다.