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


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인터페이스를 구현합니다 .

WCFSilverlight 에서 톤을 사용하여 아래 클래스와 같이 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.