C # 3.0 자동 속성 — 유용합니까? [닫은]


155

참고 : 이것은 C #을 시작할 때 게시되었습니다. 2014 년 지식을 바탕으로 자동 속성은 C # 언어에서 일어난 최고의 일 중 하나라고 진정으로 말할 수 있습니다.

개인 및 공용 필드를 사용하여 C #에서 속성을 만드는 데 익숙합니다.

private string title;
public string Title
{
    get { return title;  }
    set { title = value;  }
}

이제 .NET 3.0에서는 자동 속성이 생겼습니다.

public string Title { get; set; }

나는 이것이 철학적 / 주관적인 질문이라는 것을 알고 있지만 각 필드에 대해 5 줄의 코드를 저장하는 것 외에는 이러한 자동 속성을 사용하는 이유가 있습니까? 내 개인적인 불만은 그 속성이 내게 물건을 숨기고 있고 나는 흑 마법의 열렬한 팬이 아니라는 것입니다.

실제로 숨겨진 private 필드는 디버거에 표시되지도 않습니다. get / set 함수가 아무 작업도하지 않는다는 사실을 감안하면 괜찮습니다. 그러나 실제로 getter / setter 로직을 구현하려면 어쨌든 private / public 쌍을 사용해야합니다.

나중에 getter / setter 논리를 변경할 수있는 기능을 잃지 않고 많은 코드 (1 줄 대 6 줄)를 저장하는 이점을 알 수 있습니다. 그러나 다시 한 번, 간단히 public 필드를 "Public string Title"없이 선언하여이를 수행 할 수 있습니다. {get; 세트; } 블록, 따라서 더 많은 코드를 절약 할 수 있습니다.

그래서 내가 여기서 무엇을 놓치고 있습니까? 왜 누군가 실제로 자동 속성을 사용하고 싶습니까?


87
"내 개인적인 불만은 그 속성들이 내게 무언가를 숨기고 있다는 것이고 나는 흑 마법의 열렬한 팬이 아니다." 어? 컴파일러가 항상 당신에게서 톤을 숨기는 것을 알고 있습니까? 어셈블리 (또는 더 정확하게는 코드의 실제 1과 0)를 작성하지 않는 한, 작성하는 모든 것은 여러분에게서 무언가를 숨기는 것입니다.
Charles Boyung

답변:


120

우리는 Stack Overflow에서 항상 사용합니다.

또한 속성 대 공용 변수 에 대한 토론에 관심이있을 수 있습니다 . IMHO는 이것이 실제로 반응이며 그 목적을 위해 훌륭합니다.


63

예, 코드 저장합니다. 당신이 그것들이 많을 때 읽기가 더 쉽습니다. 더 빨리 작성하고 유지 관리하기 쉽습니다. 코드 저장은 항상 좋은 목표입니다.

다른 범위를 설정할 수 있습니다.

public string PropertyName { get; private set; }

따라서 속성은 클래스 내에서만 변경할 수 있습니다. 리플렉션을 통해 개인 setter에 계속 액세스 할 수 있으므로 실제로 변경 불가능한 것은 아닙니다.

C # 6부터 진정한 readonly속성, 즉 생성자 외부에서 변경할 수없는 불변 속성을 만들 수도 있습니다 .

public string PropertyName { get; }

public MyClass() { this.PropertyName = "whatever"; }

컴파일 시간에 다음과 같이됩니다.

readonly string pName;
public string PropertyName { get { return this.pName; } }

public MyClass() { this.pName = "whatever"; }

멤버가 많은 불변 클래스에서 이것은 많은 초과 코드를 절약합니다.


"따라서 기능을 잃지 않습니다." 어떻게 디버깅합니까?

2
@wal-디버깅 할 것이 무엇입니까? 이 관점에서 기본적으로 멤버 변수를 다루고 있습니다.
Keith

6
@wal-멤버 변수에 액세스 할 수있는 것처럼 중단 점을 넣을 수 있으며 단계적으로 들어갈 수 없습니다. 하지만 왜 그러고 싶습니까? 자동 속성이 실제로하는 일은 사소하고 자동으로 생성되는 것입니다. 버그가있을 가능성이 극히 적습니다.
Keith

3
이걸 Keith 밖에서 가져 가야 할지도 몰라요. :)

1
그러나 좋습니다. myObj.Title에 대한 많은 setter 호출이 있다고 가정합니다. 값이 "text"에서 null로 변경되는 위치, 즉 조건부 중단 점을보고 싶습니다. 당신은 그것을 어떻게 달성합니까? setter에 중단 점을 설정할 수도 없습니다
wal

46

속성 대신 필드를 사용할 때의 세 가지 큰 단점은 다음과 같습니다.

  1. 필드에는 데이터 바인딩 할 수 없지만 속성에는 할 수 있습니다.
  2. 필드를 사용하여 시작하면 나중에 (쉽게) 속성으로 변경할 수 없습니다.
  3. 필드에 추가 할 수없는 속성에 추가 할 수있는 몇 가지 특성이 있습니다.

7
"필드를 사용하기 시작하면 나중에 (쉽게) 속성으로 변경할 수 없습니다."미안하지만 그 이유는 무엇입니까?
Homam

6
@Homam 주로 필드에 리플렉션을 사용하는 모든 소비자 코드는 FieldInfo 사용에서 PropertyInfo로 전환해야하기 때문에 깨집니다.
WCWedin

9
@Homam 또한 필드를 속성으로 변경하면 이진 호환성이 깨져서 필드의 모든 소비자가 다시 컴파일해야합니다.
Odrade 2011 년

1
재 컴파일 및 반사 문제는 제쳐두고 Visual Studio를 사용하여 필드를 캡슐화하는 것은 매우 쉽습니다. Ctrl-R + E를 사용하면 필드를 적절한 getter / setter를 사용하여 속성으로 바꿀 수 있습니다. (또는 필드를 마우스 오른쪽 버튼으로 클릭하고 필드를 리팩터링하고 캡슐화합니다).
JoeBrockhaus 2011

@Hommam 필드는 lvalue (변수)이고 속성은 그렇지 않습니다. 필드 일 때 컴파일되었을 수있는 항목은 속성 일 때 그렇지 않을 수 있습니다.
Mark

29

저는 개인적으로 자동 속성을 좋아합니다. 코드 줄을 저장하는 데있어 문제점은 무엇입니까? getter 또는 setter에서 작업을 수행하려는 경우 나중에 일반 속성으로 변환하는 데 문제가 없습니다.

말했듯이 필드를 사용할 수 있으며 나중에 논리를 추가하려면 속성으로 변환해야합니다. 그러나 이것은 반사를 사용하는 데 문제가 될 수 있습니다.

또한 속성을 사용하면 필드로 수행 할 수없는 getter 및 setter에 대해 다른 액세스 수준을 설정할 수 있습니다.

var 키워드와 동일하다고 생각합니다. 개인적인 취향의 문제입니다.


29

C ++를 만든 Bjarne Stroustrup에서 :

특히 get 및 set 함수가 많은 클래스를 싫어합니다. 이것은 종종 처음에 수업이 아니어야한다는 표시입니다. 데이터 구조 일뿐입니다. 그리고 그것이 정말로 데이터 구조라면 데이터 구조로 만드십시오.

그리고 그거 알아? 그가 맞아. 단순히 "객체 지향"작업이기 때문에 get / set 내에서 실제로 아무것도하지 않고 단순히 get 및 set에서 private 필드를 래핑하는 빈도입니다. 이것은 문제에 대한 Microsoft의 솔루션입니다. 기본적으로 바인딩 할 수있는 공개 필드입니다.


2
나는 이것이 더 많은 포인트를 가져야한다고 생각한다. 너무나 많은 사람들이 자동 속성을 영광스러운 공개 필드에 지나지 않는 끔찍하게 캡슐화 된 (또는 전혀 캡슐화되지 않은) 클래스를 작성하는 데 대한 청신호로 간주합니다. 물론 이것은 사람들이 도구 자체보다는 도구를 사용하는 방법에 더 많은 문제이지만, 일반적으로 속성을 논의 할 때 언급하는 것이 중요하다고 생각합니다.
사라

18

아무도 언급하지 않은 것으로 보이는 한 가지는 불행히도 자동 속성이 불변 객체 (일반적으로 불변 구조체)에 유용하지 않다는 것입니다. 이를 위해 정말로해야 할 일 :

private readonly string title;
public string Title
{
    get { return this.title; }
}

(여기서 필드는 전달 된 매개 변수를 통해 생성자에서 초기화 된 다음 읽기 전용입니다.)

따라서 이것은 단순 get/ 자동 private set속성에 비해 장점이 있습니다 .


구조체가 속성을 변경하면 새 구조체가 생성됩니다. 내부적으로 변경 불가능한 참조 유형을 원할 경우에만 문제가 될 수 있습니다. 필요한 이유를 알 수 없습니다.
Keith

@Keith : 첫 번째 문장이 사실적으로 잘못된 것 같습니다.
Domenic

3
public string Title { get; private set; }똑같은 결과가 나오지 않을까요 ? 물론 클래스 내부에서 변경할 수 있지만 그렇게하면 다른 문제가 있습니다 ... : p
Svish

2
@Svish는 - 읽기 전용 C #으로 키워드가 인수의 사용은 우리가이 "다른 문제"숨어있는 것을 의미하기 때문에 사용해서는 안됩니다
자이드 마수드를

2
외부 API의 관점에서 보면 별 차이가 없을 것입니다. 따라서 원하는 경우 자동 속성을 사용할 수 있습니다. 당신이 뭔가 할 수 있다면 가장 좋은 것은 물론 것public string Title { get; private readonly set; }
Svish

12

인터페이스 정의에서 속성을 사용할 수 있기 때문에 항상 공용 필드 대신 속성을 만듭니다. 인터페이스 정의에서는 공용 필드를 사용할 수 없습니다.


8

자동 속성은 C #의 다른 어떤 것만큼이나 마술입니다. 일단 일반적인 C # 속성으로 확장하는 것이 아니라 IL로 컴파일하는 관점에서 생각해 보면 다른 많은 언어 구조보다 훨씬 덜 마술입니다.


5

나는 항상 자동 속성을 사용합니다. C # 3 이전에는 모든 입력에 신경을 쓸 수 없었고 대신 공용 변수를 사용했습니다.

내가 놓친 유일한 것은 이것을 할 수 있다는 것입니다.

public string Name = "DefaultName";

속성이있는 생성자로 기본값을 이동해야합니다. 지루한 :-(


4
C # 6의 자동 속성 이니셜 라이저를 사용하면 곧이 작업을 수행 할 수 있습니다. public string Name { get; set; } = "DefaultName"; blogs.msdn.com/b/csharpfaq/archive/2014/11/20/…
Carlos Muñoz

5

직관적이고 코드 줄을 줄이는 구조는 큰 장점이라고 생각합니다.

이러한 기능은 Ruby와 같은 언어를 강력하게 만드는 요소입니다 (과잉 코드를 줄이는데도 도움이되는 동적 기능).

Ruby는이 모든 것을 다음과 같이 가지고 있습니다.

attr_accessor :my_property
attr_reader :my_getter
attr_writer :my_setter

2

내가 가진 유일한 문제는 그들이 충분히 멀리 가지 않는다는 것입니다. 자동 속성을 추가 한 컴파일러의 동일한 릴리스에 부분 메서드가 추가되었습니다. 그들이 두 가지를 합치 지 않은 이유는 나를 넘어선 다. 단순한 "부분적 On <PropertyName> Changed"는 이러한 것들을 정말 유용하게 만들었습니다.


다른 메서드 안에 여러 개의 부분 메서드를 넣을 수 있습니다. 어떤 종류의 자동 패턴을 만드는 것은 혼란 스러울 것입니다.
Matthew Whited

2

간단하고 짧으며, 속성의 본문 어딘가에 실제 구현을 생성하려는 경우 유형의 외부 인터페이스가 손상되지 않습니다.

저것과 같이 쉬운.


1

여기서 주목해야 할 점은 제가 이해하기로 이것은 C # 3.0 쪽의 구문 설탕 일 뿐이며 컴파일러에 의해 생성 된 IL이 동일하다는 것을 의미합니다. 나는 흑 마법을 피하는 것에 동의하지만, 같은 일에 대해 똑같이 적은 줄을 쓰는 것이 일반적으로 좋은 일입니다.


1

제 생각에는 항상 공개 필드 대신 자동 속성을 사용해야합니다. 즉, 여기에 타협이 있습니다.

속성에 사용할 명명 규칙을 사용하여 내부 필드로 시작 합니다. 당신이 처음으로

  • 어셈블리 외부에서 필드에 액세스해야합니다.
  • getter / setter에 로직을 첨부해야합니다.

이 작업을 수행:

  1. 필드 이름 변경
  2. 비공개로
  3. 공공 재산 추가

클라이언트 코드는 변경할 필요가 없습니다.

하지만 언젠가는 시스템이 성장하고이를 별도의 어셈블리와 여러 솔루션으로 분해 할 것입니다. 이런 일이 발생하면 Jeff가 언급했듯이 공개 필드를 공개 속성으로 변경하는 것은 API 변경 사항을 깨는 것이기 때문에 노출 된 모든 필드가 다시 나타나게됩니다 .


0

CodeRush를 사용하는데 자동 속성보다 빠릅니다.

이것을하기 위해:

 private string title;
public string Title
{
    get { return title;  }
    set { title = value;  }
}

총 8 번의 키 입력이 필요합니다.


5
CTRL과 V를 누르고 있으면 많은 것을 붙여 넣을 수 있습니다. / 정말 빠르게 /하지만 그것이 '더 나은'것은 아닙니다. 이것은 원래 질문에 어떻게 대답합니까?
JBRWilkinson

0

코드 스 니펫을 사용하면 동일한 이름의 자동 속성은 총 7 번의 키 입력이됩니다.)


0

@Domenic : 모르겠어요 .. 자동 속성으로이 작업을 수행 할 수 없습니까? :

public string Title { get; }

또는

public string Title { get; private set; }

이것이 당신이 말하는 것입니까?


당신은 할 수 있지만 (후자는 컴파일되지 않을 것입니다), 그러면 필드는 당신의 객체 안에서 불변하지 않습니다.
Domenic

주의 할 점은 읽기 전용 플래그가 지정되면 구조체 만 변경할 수 없으며 클래스는 할당 할 수 없습니다.
Guvante

0

자동 속성에 대한 나의 가장 큰 불만은 시간을 절약하도록 설계되었다는 것입니다.하지만 나중에 완전한 속성으로 확장해야하는 경우가 많습니다.

VS2008에서 누락 된 것은 Explode Auto-Property 리 팩터입니다.

캡슐화 필드 리팩터링 이 있다는 사실은 공용 필드를 사용하기 위해 더 빠르게 작업하는 방식을 만듭니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.