사유 재산을 만들어야합니까?


19
private string mWhatever;

private string Whatever
{
    get
    {
        return this.mWhatever;
    }
    set
    {
        this.mWhatever = value;
    }
}

개인이든 아니든, 모든 회원을 위해 속성을 만드는 사람들을 보았습니다. 모든 멤버에 대해 속성을 사용하지 않으면 불일치가 발생하고 멤버는 액세스 권한이 있습니다 (클래스 범위 내에서 둘 다 액세스 할 수 있으므로).

답변:


17

짧은 대답 : 예 , 필요한 경우. 그렇지 않으면 다음과 같은 자동 구현 속성 getter 및 setter를 사용하십시오.private string Whatever { get; set;}

  • 도메인 닫기 접근 방식을 사용하는 경우 매우 편리합니다
  • 값을 설정할 때 특정 논리 를 확인해야 할 때도 편리 합니다.

다음은 개인 설정 도구를 사용하는 경우에 대한 전체 설명입니다. C # property usage .


필요한 경우 나중에 부동산을 공개하는 것도 정말 쉽습니다.
— Tom Pickles

4
가까운 도메인 접근 방식 은 무엇입니까 ?
— Trisped

1
나는 클래스의 속성에서 개인 세터를 언급하고있었습니다. 값을 설정하기 전에 객체에서 설정 값에 직접 액세스하지 못하고 논리 검사를 용이하게해야합니다.
— Yusubov

공개 세터 / 게터가있는 개인 변수를 갖는 경우 (단순한 경우에도) 코드가 라이브러리로 컴파일 된 경우 순진한 세터 / 게터를 사이드가있는 코드로 바꾸면 서명이 변경되지 않습니다. 간단한 공용 변수를 대신 사용하는 경우 라이브러리 시그니처를 원시가 아닌 setter / getter가있는 개인으로 변경하면 라이브러리 서명이 변경됩니다. .. 라이브러리가 그런 식으로 변경되면 라이브러리 소비자는 다시 컴파일해야합니다.
— 오리온 엘렌 질

12

여기에 좋은 답변이 있지만 대부분은 귀하의 질문 중 하나를 놓친 것 같습니다.

개인이든 아니든, 모든 회원을 위해 속성을 만드는 사람들을 보았습니다.

나는 이것이 모든 단일 구성원에 대해 사전에 거의 필요하지 않다고 생각한다 . 로 시작

 private string Whatever;

나중에이 특정 멤버에 대한 캡슐화 또는 조건부 중단 점이 필요한 지점에 도달하면 대부분의 경우 사용하는 코드를 변경하지 않고도 동일한 이름의 속성으로 대체 할 수 있습니다 Whatever. 그러나 미묘한 차이점이 있다는 것을 명심하십시오. 이 SO 게시물 (Emmad Kareem의 +1 링크) 에서 Brian Rasmussen의 답변을 참조하십시오 .


+1 또한, 당신은 맞습니다, 대부분의 답변이 원래의 질문 포인트를 놓쳤습니다, 우리는 전형적인 IT
— 전문가입니다

현장을 재산으로 리팩토링하는 것은 악몽이다. 모든 소비자를 다시 컴파일해야합니다. 커스텀 로직을 포함하도록 자동 속성을 변경하는 것은 쉬운 일입니다. 코드에 리 팩터가 표시 될 가능성이 조금이라도 있다면, 시작부터 속성을 사용하면 작업이 훨씬 줄어 듭니다.
— Dan

@ Dan : 대부분의 프로젝트에서 노력이 거의 동일하다는 것을 알았습니다 . 두 경우 모두 다시 컴파일해야합니다 . 그럼에도 불구하고 속성, 특히 자동 속성을 사용하면 반사 또는 "out"매개 변수의 멤버 변수 사용과 관련된 일부 미묘한 문제를 피할 수 있다고 생각합니다.
— Doc Brown

@DocBrown 어쨌든 그것은 모든 것을 다루는 진술이 아닙니다. 단순하게 유지하고 필드를 사용해야하는 많은 이유가 있습니다. 리 팩터를 예측할 수 있다면 미묘한 문제조차 고려할 가치가 있습니다.
— Dan

7

이 방법의 가장 큰 장점 중 하나는 변수가 변경 될 때 제어 할 수 있다는 것 입니다.

다음을 고려하세요.
큰 프로젝트를 디버깅하고 있습니다. 특정 메소드에서 예외가 발생합니다. 중단 점을 설정하고 특정 멤버 변수의 값이 잘못되었음을 나타냅니다. 코드 가이 변수에 매우 광범위하게 의존하고 수백 가지의 쓰기 사용법을 발견 했다고 가정하십시오 ( 스파게티 시나리오 ). 따라서 이러한 사용량 중 어떤 값에 나쁜 값이 할당 되었는지 알 수 없습니다 .
코드가 다중 스레드 인 경우 디버깅이 실제 악몽이 될 수 있습니다.

속성을 사용하면 setter에 중단 점을 설정할 수 있습니다 . 조건과 결합하면 한 번에 못 박힐 수 있습니다.

VC ++에는 데이터 중단 점이 있지만 관리되지 않는 코드에서만 사용할 수 있습니다.


1

속성을 사용하지 않는 경우 다른 옵션은 필드를 사용하여 변수 데이터를 저장하는 것입니다. 속성과 필드에는 큰 차이가 있습니다. 이러한 차이점의 대부분은 필드 대 속성 입니다. 차이점을 연구 한 다음 응용 분야의 요구에 따라 선택하십시오. 그러나 속성 대신 필드를 사용하는 것은 특성과 단점으로 인해 일반적인 OO 관행이 아닙니다.


1

개인 속성은 클래스 내부의 동작을 캡슐화하는 데 매우 유용 할 수 있습니다. 그것들이 사적이라고해서 속성이 제공하는 구문 설탕을 이용해서는 안된다는 의미는 아닙니다.


그러나 주어진 예는 좋지 않습니다. 이와 같은 상용구 속성 게터와 세터는 거의 항상 나쁜 생각입니다. C # 3.0 이상을 사용하는 경우 자동 속성 이 훨씬 더 좋습니다.

private string Whatever { get; set; };

이것은 더 짧고 깨끗하며 훨씬 더 읽기 쉽습니다. 사실 그것은 단순히 변수를 선언하는 것보다 길다.

가장 중요한 것은 자동 속성은 프로그램의 나머지 의미를 변경하지 않고도 언제든지 전체 속성으로 변환 할 수 있다는 것입니다. 따라서 유효성 검사 또는 오류 처리를 추가해야하는 경우 쉽게 수행 할 수 있습니다.


나는 항상 읽기 전용 속성을 가질 수 없으며 생성자에서 값에 쓸 수만 있도록 강제하는 것은 부끄러운 일이라고 생각했지만 ( 불변의 유형을 선호합니다 ) C # 6.0에서 다음 과 같이 추가 되었습니다. "자동 속성 이니셜 라이저"를 통해 다음을 수행 할 수 있습니다.

private string Whatever { get; } = ...;

또는

private string Whatever { get; };

와 함께

    Whatever = ...;

생성자에서.


0

개인 속성에 대해이 작업을 반드시 수행 할 필요는 없지만 액세스 방법을 변경하지 않고 속성이 기본 값을 가져 오거나 설정하는 방법을 수정할 수 있습니다.

예를 들어, 기본 값 설정 방법 수정 :

private string Whatever
{
    get
    {
        return this.mWhatever;
    }
    set
    {
        this.mWhatever = string.IsNullOrEmpty(value) ? string.Empty : value;
    }
}

0

네

개인적으로 이것을 캐싱 메커니즘으로 사용하며이를 속성 수준 캐싱 이라고 부릅니다 .

private List<User> users;
private List<User> Users
{
    get
    {
        if(users == null) users = new UserManager().GetUsers();
        return users;
    }
}

이제는 수업 내 다른 장소 Users에서 users필드 대신 속성을 사용 합니다.

다른 가능한 상황은 필드에서 일부 논리를 구현하지만 클래스에서 중앙 집중식으로 구현하려는 경우입니다. 따라서 GetFoo()메소드 또는 필드 의 Foo특성을 모두 작성할 수 있습니다 foo.

private string foo;
private string Foo
{
    get
    {
        return "Mr. " + foo;
    }
}

0

고려해야 할 사항 :

실제 속성은 구현 세부 사항입니다. OOP의 목표 중 하나는 가능한 경우 구현 세부 정보의 노출을 시도하고 최소화하는 것입니다.

그 이유는 속성을 숨기고 게터와 세터를 통해서만 노출하면 훨씬 더 많은 제어가 가능하기 때문입니다. 예를 들어, getter는 입력을 검증하고 특성이 유효하지 않은 상태로 설정되는 것을 방지 할 수 있습니다. 값을 변경하는 기능이 시간 결정적인 경우 세터는이를 방지 할 수 있습니다. 게터는 어떤 이유로 든 실제 값을 얻는 것이 비싸면 초기화 지연 및 / 또는 캐싱을 수행 할 수 있습니다.

게터와 세터가 노출되어 있고 속성이 숨겨져 있다는 것은 때때로 속성이 전혀 필요하지 않다는 것을 의미합니다. getter는 호출시 값을 계산하거나 다른 곳이나 작업을 사양에 맞출 수있는 모든 것을 위임 할 수 있습니다. 수업에서 중요한 것은 정보가 내부적으로 표현되는 방식이 아니라 클래스에서 액세스 할 수있는 정보입니다.

물론, 수업 이외의 외부에서 부동산에 직접 액세스 할 수있는 부정적인 결과가 없다면, 공개해야합니다. 그러나 내 경험상 그러한 경우는 상대적으로 적고 멀리 있습니다.


0

나는 이것이 오래된 질문이라는 것을 알고 있으며 @Yusubov가 말한 모든 것이 정확하지만 세터의 특정 논리 에 대한 두 번째 글 머리 기호와 관련하여 아무도 이것을 특별히 언급하지 않았기 때문에 수업을 할 때 완벽한 예가 될 것입니다. INotifyPropertyChanged인터페이스를 구현합니다 .

WCF 및 Silverlight 에서 톤을 사용하여 아래 클래스와 같이 setter의 논리를 통해 특정 속성이 언제 변경 되었는지 알 수 있습니다 .

public class Settings : INotifyPropertyChanged
{
    public Settings() 
    { 
        this.CountryField = String.Empty; 
    }

    private string CountryField;
    public string Country
    {
        get { return this.CountryField; }
        set
        {
            if (Object.ReferenceEquals(this.CountryField, value)) { return; }

            this.CountryField = value;
            this.RaisePropertyChanged("Country");
        } 
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler propertyChanged = this.PropertyChanged;

        if (propertyChanged != null)
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.