2009-05-11 7 views
6

일부 내부 유효성 검사를 수행 할 개인 변수가 있고 그 유효성을 한 곳에서 유지하려면 필자는 getter/setter 및 getter/setter 만 액세스하십시오. 다른 코드가 private 변수에 액세스 할 수 없기 때문에 public 속성을 처리 할 때 유용합니다. 그러나 클래스 자체 내부의 객체를 처리 할 때 getter/setter를 적용 할 수있는 방법이 있습니까?개인 속성에 대한 개인 변수의 액세스/설정 액세스

private int _eyeOrientation; 

    private int eyeOrientation 
    { 
    get 
    { 
     return _eyeOrientation; 
    } 
    set 
    { 
     if (value < 0) 
     { 
      _eyeOrientation = 0; 
     } 
     else 
     { 
      _eyeOrientation = value % 360; 
     } 
    } 
    } 

문제는 여기에 클래스의 다른 기능은 실수로 수정할 수 있음을 되 흥분한 혼란에 프로그램을 던질 것이다

_eyeOrientation = -1;

. 컴파일러 오류를 던질 수있는 방법이 있습니까?

+7

그 코더가 더 이상 같은 클래스 내에서 다른 기능을 신뢰할 수없는 슬픈 날 :) – codeulike

답변

10

각도 유형이 필요합니다.

// Non mutable Angle class with a normalized, integer angle-value 
public struct Angle 
{ 
    public Angle(int value) 
    { 
    Value = value; 
    } 

    private angle; 
    public Value 
    { 
    get { return angle; } 
    private set { angle = Normalize(value); } 
    } 

    public static int Normalize(int value) 
    { 
    if (value < 0) return 360 - (value % 360); 
    return value % 360; 
    } 
} 

public class SomeClass 
{ 
    public Angle EyeOrientation { get; set; } 
} 

당신이 값의 특정 종류가있는 경우, 각도, 돈, 무게 또는 무엇이든 같이, 그것은 그것에게 자신의 유형을 만들 수있는 좋은 실천이 값 자체가 INT, 소수에 저장되어있는 경우에도 항상 이 유형은 인터페이스를보다 선명하고 타입 안전합니다. 어떤 방법의 인수로 각도 또는 정수 값을 예상하는 경우에는 동일하지 않습니다.

4

중첩 된 클래스에서 정의 할 수 있습니다.

public class NeedsEye 
{ 

    Eye _eye = new Eye(); 

    public NeedsEye() 
    { 
     // now, here, any access to the property must be made through the 
     // _eye variable. The Eye class has access to any of the properties 
     // and members of the NeedsEye class, but the NeedsEye class has not 
     // any access to members of the Eye class. 
    } 

    private class Eye 
    { 
     private int _orientation; 

     public int Orientation 
     { 
      get { return _orientation; } 

      if (value < 0) 
      { 
       _eyeOrientation = 0; 
      } 
      else 
      { 
       _eyeOrientation = value % 360; 
      }  
     } 
    } 
} 
1

개인 속성과 공용 getters/setter를 개인 클래스에 넣기 만하면됩니다.

그러면 getter 및 setter 만 개인 속성에 액세스 할 수 있습니다.

과도 함이지만 작동합니다. :)

9

일반적으로 걱정할 필요가 없습니다. 클래스 자체에 검사를 넣지 않으려는 경우에도 클래스 멤버가 해당 속성을 사용할 수 있습니다.

클래스가 너무 커져서 클래스 내부의 메소드를 더 이상 신뢰하지 못하면 리팩토링을 시작하고 더 쉽게 관리 할 수있는 더 작은 클래스로 나누어야 할 때라고 생각합니다.

+0

는 내가 접근 가능한 한 엄격하기 위해 노력하고있어 개인 프로젝트에서 일하고 있어요. 단지 당신이 필요로하는 객체에 의해서만 모든 객체에 접근 할 수 있는지를보기 위해서입니다. 좋은 코딩 방법을 고수한다면 이것들이 필요하지 않지만 가능하다면 나는 호기심이 많았다. – DevinB

1

당신은 GET 외부 private 멤버에 직접 액세스를 허용하지 코딩 규칙을 강제로 볼 수 있었다 툴에 따라/좀 더 많은 작업이 될 수

을 설정하지만 당신은 래퍼의 시리즈를 만들 필요가 없습니다 수업.

3

필드에 액세스하려고하면 컴파일러에서 경고를 생성하고 getter/setter 속성은 suppress that warning이되도록 필드를 쓸모없는 것으로 표시 할 수 있습니다.

억제해야 할 경고 코드는 CS0612 for the plain Obsolete attributeCS0618 if the attribute has a custom message입니다.

일반적으로 나는 이것을 약간 해킹으로 생각하고 가능하다면 그것을 피하려고합니다. 더 나은 해결책은 코드에 적절하게 주석을 달고 동료 개발자를 훈련시켜 그들이 올바른 일을하도록하는 것입니다.

[Obsolete("Please use the EyeOrientation property instead.")] 
private int _eyeOrientation; 

public int EyeOrientation 
{ 
    #pragma warning disable 612, 618 
    get 
    { 
     return _eyeOrientation; 
    } 
    set 
    { 
     _eyeOrientation = (value > 0) ? value % 360 : 0; 
    } 
    #pragma warning restore 612, 618 
} 
+1

(+1) 그건 독창적 인 둥근 해결책입니다. – DevinB

+0

좋은 생각인데, 음수 각도를 양수로 정규화 할 수 있기 때문에 0으로 설정하지 않을 것입니다. -10 ° == 350 °. –

+0

@Stefan, 동의합니다. 질문에 예제 코드의 기능을 복제하고있었습니다. – LukeH

관련 문제