Programing

C #에서 개인 속성을 사용해야하는 이유가 있습니까?

lottogame 2020. 4. 24. 08:03
반응형

C #에서 개인 속성을 사용해야하는 이유가 있습니까?


방금 C # 속성 구문개인 액세스 수정 자 와 함께 사용할 수 있음을 깨달았습니다 .

private string Password { get; set; }

비록 이것이 기술적으로 흥미롭지 만, 개인 분야식이 훨씬 적기 때문에 언제 사용할 것인지 상상할 수 없습니다 .

private string _password;

그리고 내부적으로 얻을 수는 있지만 설정 하거나 설정할 없지만 개인 필드를 얻을 수없는 경우를 상상할 수 없습니다 .

private string Password { get; }

또는

private string Password { set; }

그러나 중첩 된 / 상속 된 클래스 의 유스 케이스가 있거나 속성을 엄격하게 유지하고 명시 적 메소드가 논리를 수행하도록하는 경향이 있지만 get / set 에 속성 값을 반환하는 대신 논리 가 포함될 수 있습니다 . 예 GetEncodedPassword().

어떤 이유로 든 C #에서 개인 속성을 사용합니까 아니면 기술적으로 가능하지만 실제로 사용되지 않는 실제 코드 구성 중 하나입니까?

추가

좋은 답변, 그들을 통해 나는 개인 재산에 대한 이러한 사용을 컬링 :

  • 개인 필드를 느리게로드해야하는 경우
  • 개인 필드에 추가 논리가 필요하거나 계산 된 값인 경우
  • 개인 필드는 디버그하기 어려울 수 있기 때문에
  • "자신에게 계약을 제시"
  • 직렬화의 일부로 노출 된 속성을 내부적으로 변환 / 단순화
  • 클래스 내에서 사용될 전역 변수 랩핑

값을 캐시해야하고 지연로드하려는 경우이를 사용합니다.

private string _password;
private string Password
{
    get
    {
        if (_password == null)
        {
            _password = CallExpensiveOperation();
        }

        return _password;
    }
}

내 코드에서 이것의 주요 사용법은 다른 사람들이 언급했듯이 게으른 초기화입니다.

필드에 대한 개인 속성의 또 다른 이유는 개인 속성이 개인 필드보다 디버그하기가 훨씬 훨씬 쉽다는 것입니다. "이 필드는 예기치 않게 설정됩니다.이 필드를 설정 한 첫 번째 발신자는 누구입니까?"와 같은 것을 자주 알고 싶습니다. 세터에 중단 점을 놓고 이동하면 더 쉽습니다. 거기에 로깅을 넣을 수 있습니다. 거기에 성능 지표를 넣을 수 있습니다. 디버그 빌드에서 실행되는 일관성 검사를 수행 할 수 있습니다.

기본적으로 코드는 데이터보다 훨씬 강력합니다 . 필요한 코드를 작성할 수있는 모든 기술이 좋습니다. 필드를 사용하면 코드를 작성할 수 없으며 속성도 마찬가지입니다.


아마도 중첩 / 상속 된 클래스의 유스 케이스가 있거나 get / set에 속성 값을 반환하는 대신 논리가 포함될 수 있습니다

속성의 getter 또는 setter에 대한 논리가 필요하지 않은 경우에도 개인적으로 사용합니다. 속성, 심지어 개인 속성을 사용하면 나중에 코드를 미래에 대비하여 필요한 경우 나중에 게터에 로직을 추가 할 수 있습니다.

속성에 결국 추가 논리가 필요할 수 있다고 생각되면 필드를 사용하는 대신 개인 속성으로 래핑하기 때문에 나중에 코드를 변경할 필요가 없습니다.


반 관련 사례 (귀하의 질문과는 다르지만), 나는 공공 재산에 개인 세터를 매우 자주 사용합니다.

public string Password 
{
    get; 
    private set;
}

이것은 공개 게터를 제공하지만 세터를 비공개로 유지합니다.


게으른 초기화는 예를 들어 깔끔한 곳입니다.

private Lazy<MyType> mytype = new Lazy<MyType>(/* expensive factory function */);

private MyType MyType { get { return this.mytype.Value; } }

// In C#6, you replace the last line with: private MyType MyType => myType.Value;

그런 다음, 다음과 같이 쓸 수 있습니다 : 한 this.MyTypethis.mytype.Value에서 느리게 인스턴스화된다는 사실을 캡슐화하십시오.

부끄러운 점 중 하나는 C #이 백킹 필드를 속성에 범위 지정 (즉, 속성 정의 내에 선언)하여 필드를 완전히 숨기고 속성을 통해서만 액세스 할 수 있도록하는 것입니다.


개인용 get 전용 속성의 좋은 사용법은 계산 된 값입니다. 여러 번 개인 전용 읽기 전용 속성을 사용했으며 내 유형의 다른 필드보다 계산을 수행했습니다. 그것은 메서드에 가치가 없으며 다른 클래스에는 흥미가 없으므로 개인 재산입니다.


내가 생각할 수있는 유일한 사용법

private bool IsPasswordSet 
{ 
     get
     {
       return !String.IsNullOrEmpty(_password);
     }
}

속성과 필드는 일대일이 아닙니다. 속성은 클래스의 인터페이스 (공개 또는 내부 인터페이스에 대해 이야기하든)에 관한 것이며 필드는 클래스의 구현에 관한 것입니다. 속성은 단순히 필드를 노출하는 방법으로 보여서는 안되며 클래스의 의도와 목적을 노출하는 방법으로 보여야합니다.

클래스를 구성하는 것에 대해 소비자에게 계약을 제시하기 위해 속성을 사용하는 것과 마찬가지로 매우 유사한 이유로 계약을 제시 할 수도 있습니다. 예, 개인 속성을 사용하는 것이 좋습니다. 때로는 사유 재산이 게으른 로딩과 같은 구현 세부 사항을 숨길 수 있습니다. 속성이 실제로 여러 필드와 측면의 대기업이거나 속성이 각 호출마다 가상으로 인스턴스화되어야한다는 사실입니다 (think DateTime.Now). 수업의 백엔드에서도 스스로를 시행하는 것이 합리적 인 경우가 있습니다.


나는 DataContractSerializer이 사용법을 지원하거나 XmlSerializer하지 않는 protobuf-net 과 같은 것들과 함께 직렬화에 사용합니다 . 직렬화의 일부로 객체를 단순화해야하는 경우에 유용합니다.

public SomeComplexType SomeProp { get;set;}
[DataMember(Order=1)]
private int SomePropProxy {
    get { return SomeProp.ToInt32(); }
    set { SomeProp = SomeComplexType.FromInt32(value); }
}

내가 항상하는 한 가지는 "전역"변수 / 캐시를 저장하는 것입니다. HttpContext.Current

private static string SomeValue{
  get{
    if(HttpContext.Current.Items["MyClass:SomeValue"]==null){
      HttpContext.Current.Items["MyClass:SomeValue"]="";
    }
    return HttpContext.Current.Items["MyClass:SomeValue"];
  }
  set{
    HttpContext.Current.Items["MyClass:SomeValue"]=value;
  }
}

나는 때때로 그들을 사용합니다. 속성에 중단 점을 쉽게 넣거나 로깅 문 등을 추가 할 수 있으면 디버깅이 쉬워집니다.

나중에 데이터 형식을 변경해야하거나 리플렉션을 사용해야하는 경우에도 유용 할 수 있습니다.


개인 속성을 사용하여 자주 사용하는 하위 속성에 액세스하기위한 코드를 줄입니다.

    private double MonitorResolution
    {
        get { return this.Computer.Accesories.Monitor.Settings.Resolution; }
    }

하위 속성이 많은 경우에 유용합니다.


get / set 메소드 (비공개 메소드 포함)로 멤버 만 수정하는 것이 일반적입니다. 이제 그 뒤에있는 논리는 get / set이 항상 특정 방식 (예 : 이벤트 발생)으로 작동한다는 것을 알기 때문에 속성 체계에 포함되지 않기 때문에 의미가 없습니다 ... 그러나 오래된 습관은 열심히 죽습니다.


속성 세트 또는 가져 오기와 관련된 논리가 있고 (게으른 초기화 생각) 속성이 클래스의 몇 곳에서 사용될 때 완벽하게 이해됩니다.

그냥 역행의 필드라면? 좋은 이유는 없습니다.


글쎄, 언급 한 사람이 없으므로 데이터를 확인하거나 변수를 잠그는 데 사용할 수 있습니다.

  • 확인

    string _password;
    string Password
    {
        get { return _password; }
        set
        {
            // Validation logic.
            if (value.Length < 8)
            {
                throw new Exception("Password too short!");
            }
    
            _password = value;
        }
    }
    
  • 잠금

    object _lock = new object();
    object _lockedReference;
    object LockedReference
    { 
        get
        {
            lock (_lock)
            {
                return _lockedReference;
            }
        }
        set
        {
            lock (_lock)
            {
                _lockedReference = value;
            }
        }
    }
    

    참고 : 참조를 잠글 때 참조 된 개체의 멤버에 대한 액세스는 잠그지 않습니다.

게으른 참조 : 게으른로드 할 때 요즘 AsyncLazy 가있는 비동기를 수행해야 할 수도 있습니다 . Visual Studio SDK 2015 이전 버전이거나 사용하지 않는 경우 AsyncEx의 AsyncLazy를 사용할 수도 있습니다 .


나는이 질문이 매우 오래되었다는 것을 알고 있지만 아래 정보는 현재 답변에 없었습니다.

내부적으로 얻을 수는 있지만 설정할 수없는 상황을 상상할 수 없습니다

의존성을 주입하는 경우 읽기 전용 속성을 나타내는 setter가 아닌 속성에 Getter를 사용하는 것이 좋습니다. 즉, 속성은 생성자에서만 설정할 수 있으며 클래스 내의 다른 코드로 변경할 수 없습니다.

또한 Visual Studio Professional은 필드가 아닌 속성에 대한 정보를 제공하므로 필드가 사용중인 항목을 쉽게 확인할 수 있습니다.

PorpField


명시 적 필드의 좀 더 이국적인 용도는 다음과 같습니다.

  • 당신 은 값 을 사용 ref하거나 사용해야 out합니다-아마도 Interlocked카운터 이기 때문에
  • 이되는 구성 A의 예를 들어 기본 레이아웃을 표현하기 위해 struct명시 적 레이아웃 (아마도 C ++ 덤프, 또는에 매핑하는 unsafe코드)
  • 역사적으로 유형은 BinaryFormatter자동 필드 처리 함께 사용되었습니다 (자동 소품으로 변경하면 이름이 변경되어 직렬 변환기가 손상됨)

참고 URL : https://stackoverflow.com/questions/3310186/are-there-any-reasons-to-use-private-properties-in-c

반응형