퍼블릭 필드와 자동 속성


353

필드를 외부 세계에 노출시키는 대신 클래스 필드에 대해 getter 및 setter 메소드 (C #의 특성)를 작성하여 캡슐화를 보호해야한다는 말이 종종 있습니다.

그러나 필드가 값을 보유하기 위해 존재하는 경우가 많으며 얻거나 설정하기 위해 계산이 필요하지 않습니다. 이를 위해 우리는 모두이 숫자를 수행합니다.

public class Book
{
    private string _title;

    public string Title
    {
          get{ return _title;  }
          set{ _title = value; }
    }
}

글쎄, 나는 고백을했습니다. 나는 모든 것을 쓸 수 없었습니다.

그런 다음 C # 3.0이 나오고 자동 속성이 추가 된 것을 볼 수 있습니다.

public class Book
{
    public string Title {get; set;} 
}

어느 것이 더 깔끔하고 고마웠지만 실제로 공공 장소를 만드는 것보다 다른 점은 무엇입니까?

public class Book
{
    public string Title;
}



1
나는 재산을 재산으로 리팩토링해야하는 길을 깨닫게되면 불필요한 두통이 생겨 개인 재산이 아닌 것을 만드는 경향이있다. 속성, 필드 및 방법 어머! 과거에 저를 물린 비 호환성을 불러냅니다.
Steven Wexler

2
prop코드는 빠른 속성을 만들 수 있습니다. 입력 prop한 다음 탭하십시오.
Tono Nam

답변:


175

A의 관련 질문 내가 얼마 전에 있었다 약간의 차이를 설명 제프의 블로그에 게시물에 대한 링크가 있었다.

속성 대 공용 변수

  • 리플렉션은 변수와 속성에 따라 다르게 작동하므로 리플렉션에 의존하는 경우 모든 속성을 사용하는 것이 더 쉽습니다.
  • 변수에 대해 데이터 바인딩 할 수 없습니다.
  • 변수를 속성으로 변경하는 것은 주요 변경 사항입니다. 예를 들면 다음과 같습니다.

    TryGetTitle(out book.Title); // requires a variable

24
"변수를 속성으로 변경하는 것은 큰 변화입니다." 물론 이것은 대부분의 개발자가 하지 않는 재사용 가능한 라이브러리를 작성할 때만 적용됩니다 .
Steven

30
또한 속성, 심지어 자동 속성도 필드가 할 수없는 가상 일 수 있습니다. 따라서 기본 클래스는 컴파일러가 자동 prop에 대해 생성 한 간단한 back-field 구현을 가질 수있는 반면 파생 클래스는 추가 유효성 검사 또는 다른 논리 / 계산을 수행 할 수 있습니다.
KeithS

28
또한 필드는 변수 이며 참조 ( ref또는 out키워드) 로 전달 될 수 있지만 속성은 접근 자 쌍이며 참조로 전달할 수 없습니다. 예를 들어 bool success = TryGetMyTitle(out myBook.Title);, 용도 out는 필드에서 작동하지만 속성에서는 작동하지 않습니다. 이것은 필드에서 속성으로의 변경이 주요 변경 인 이유의 분명한 예입니다!
Jeppe Stig Nielsen

2
@KyleBaran 아니요, 속성은 변수가 아닌 접근 자 메서드 쌍이기 때문에 의미가 없습니다. 일반적으로 수행 할 작업은 로컬 변수를 선언하고 (로컬 값을 로컬 변수에 넣은 속성을 읽고) 로컬 변수를 ref/ 로 전달한 out다음 속성을 로컬 변수의 값으로 설정하는 것입니다. 그러나 호출 된 메소드 자체는 속성에 액세스하지 않고 사용자가 만든 로컬 변수에 액세스합니다.
Jeppe Stig Nielsen

5
@theberserker True, C # 6 public int Foo { get; }에서는 읽기 전용 백업 필드로 자동 속성을 만들 수 있지만 그렇게 할 수 있습니다 .
Michael Stum

83

API 문제를 무시하면 속성 사용에있어 가장 가치있는 것은 디버깅입니다.

CLR 디버거는 데이터 중단 점을 지원하지 않습니다 (대부분의 기본 디버거는 지원). 따라서 클래스의 특정 필드를 읽거나 쓸 때 중단 점을 설정할 수 없습니다. 이는 특정 디버깅 시나리오에서 매우 제한적입니다.

속성은 매우 얇은 방법으로 구현되므로 값을 읽고 쓸 때 중단 점을 설정할 수 있습니다. 이것은 들판 위에 큰 다리를 제공합니다.


2
10 년 후, 적어도 .NET Core의 경우 데이터 중단 점이 있습니다.
Luaan

72

필드에서 속성으로 변경하면 계약이 깨집니다 (예 : 모든 참조 코드를 다시 컴파일해야 함). 따라서 다른 클래스 (공개 (일반적으로 보호되는) 멤버)와의 상호 작용 지점이있는 경우 향후 성장을 계획하려고합니다. 항상 속성을 사용하여 수행하십시오.

오늘날 자동 속성으로 만드는 것은 아무 것도 아닙니다. 3 개월 동안 줄을 서서히로드하고 게터에 널 체크를하고 싶다는 것을 알게되었습니다. 필드를 사용한 경우 어셈블리에 의존하는 사람 및 대상에 따라 최악의 경우 재 컴파일 변경이 가능합니다.


9
나는 '반사', '인터페이스'또는 '재정의'라는 단어를 사용하지 않기 때문에이 답변을 좋아했습니다. ( '계약'에 대해 너무 나쁨)

65

아무도 언급하지 않았기 때문에 : 인터페이스에서 필드를 정의 할 수 없습니다. 따라서 속성을 정의하는 특정 인터페이스를 구현해야하는 경우 자동 속성이 때로는 좋은 기능입니다.


1
속성을 정의하는 인터페이스가 필요하면 추상 클래스 여야한다고 말하고 싶습니다. c #을 사용하면 인터페이스에서 속성을 정의 할 수 있다고해서 반드시 사용해야한다는 의미는 아닙니다. 나쁜 디자인입니다.
Odys

8
@ odyodyodys-이것이 나쁜 디자인이라는 데 동의하지 않습니다. 당신의 근거를 설명해 주시겠습니까?
Zaid Masud

4
@ odyoneodys 동의 zooone9243 : Imp, 디자인 관점에서 속성 선언과 getter / setter 쌍 선언 (인터페이스의 일반적인 관행) 사이에는 차이가 없습니다.
MartinStettner

22
@ zooone9243, + MartinStettner : 6 개월 전부터 그 이후로 많은 것을 배웠습니다. 나는 그것을 되찾고있다 :)
Odys

47

종종 간과되고 다른 답변에서 언급되지 않은 큰 차이 : 재정의 . 속성을 가상으로 선언하고 재정의 할 수 있지만 공용 멤버 필드에 대해서는 동일하게 수행 할 수 없습니다.


10

버전 관리 및 API 안정성에 관한 모든 것입니다. 버전 1에는 차이가 없습니다. 그러나 나중에 버전 2에서 일부 유형의 오류 검사와 함께이 속성을 속성으로 만들어야한다고 결정하면 API를 변경할 필요가 없습니다. 속성의 정의


10

공용 필드에 비해 자동 구현 된 속성의 또 다른 장점은 집합 접근자를 개인 또는 보호로 설정하여 공용 필드보다 제어가 잘 정의 된 개체 클래스를 제공 할 수 있다는 것입니다.


8

필드를 만드는 데 아무런 문제가 없습니다 public. 그러나 필드 를 사용 getter/setter하여 만드는 private것은 캡슐화가 아니라는 것을 기억하십시오 . IMO, 다른 기능에 관심이 없다면, 그 기능을 Property만들 수도 public있습니다.


1

컬렉션 또는 데이터베이스와 비교하여 제목이 고유한지 나중에 확인하기로 결정한 경우 제목에 종속 된 코드를 변경하지 않고 속성에서 해당 제목을 수행 할 수 있습니다.

공용 속성 만 사용하면 유연성이 떨어집니다.

계약을 어 기지 않는 추가적인 유연성은 속성 사용에있어 가장 중요하며 실제로 유연성이 필요할 때까지 자동 생성이 가장 적합합니다.


0

모든 코드와 테스트 이유뿐만 아니라 매우 유용하다고 생각되는 한 가지는 속성 대 필드 인 경우 Visual Studio IDE가 속성이 아닌 필드에 대한 참조를 표시한다는 것입니다.


0

나의 POV 후 한 연구

  1. 확인.
  2. 접근자를 재정 의하여 속성의 동작을 변경하도록 허용합니다.
  3. 디버깅 목적. 접근 자에 중단 점을 설정하여 속성이 언제, 어떻게 변경되는지 알 수 있습니다.
  4. 필드 만 설정할 수 있습니다. 예를 들어 public set () 및 private get ()입니다. 공공 장소에서는 불가능합니다.

실제로 우리에게 더 많은 가능성과 확장 성을 제공합니다.

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