[c#] 게터, 세터 및 속성 모범 사례. 자바 대 C #

저는 지금 C # 수업을 듣고 있으며 최선의 방법을 찾으려고 노력하고 있습니다. 저는 Java 배경에서 왔으므로 Java 모범 사례에만 익숙합니다. 저는 C # 초보자입니다!

Java에서 개인 속성이 있으면 이렇게합니다.

private String name;

public void setName(String name) {
   this.name = name;
}

public String getName() {
   return this.name;
}

C #에서는 여러 가지 방법이 있음을 알 수 있습니다.

Java처럼 할 수 있습니다.

private string name;

public void setName(string name) {
   this.name = name;
}

public string getName() {
   return this.name;
}

또는 이렇게 할 수 있습니다.

private string name;

public string Name {
   get { return name; }
   set { name = value; }
}

또는:

public string Name { get; set; }

어떤 것을 사용해야하며 각 접근 방식과 관련된주의 사항이나 미묘한 점은 무엇입니까? 클래스를 만들 때 Java에서 알고있는 일반적인 모범 사례를 따르고 있습니다 (특히 효과적인 Java 읽기). 예를 들어, 저는 불변성을 선호합니다 (필요한 경우에만 setter 제공). 저는 이러한 관행이 C #에서 setter와 getter를 제공하는 다양한 방법에 어떻게 적용되는지 궁금합니다. 본질적으로 Java 세계의 모범 사례를 C #으로 어떻게 변환합니까?

편집하다

나는 이것을 Jon Skeet의 답변에 대한 의견으로 게시했지만 오래되었습니다.

사소하지 않은 속성 (즉, 상당한 처리 및 유효성 검사 포함)은 어떻습니까? 나는 아직도 공용 속성을 통해 만에 캡슐화 된 논리에 노출 수 getset? 전용 setter 및 getter 메서드 (관련 처리 및 유효성 검사 논리 포함)를 사용하여이 작업을 수행해야하는 이유는 무엇입니까?



답변

C # 6 이전

나는 사소한 속성을 위해 이들 중 마지막을 사용할 것입니다. getter와 setter가 모두 공용 이므로 이것을 공용 속성이라고합니다.

불변성은 자동으로 구현 된 속성으로 인해 약간의 고통입니다. getter 만있는 자동 속성을 작성할 수 없습니다. 가장 가까운 곳은 다음과 같습니다.

public string Foo { get; private set; }

이것은 정말로 불변 하지 않습니다 . 클래스 밖에서는 불변입니다. 따라서 실제 읽기 전용 속성을 대신 사용할 수 있습니다 .

private readonly string foo;
public string Foo { get { return foo; } }

당신은 확실히 쓰고 싶지 않아 getName()setName(). 에서 일부 의 경우 그것은 그들이 비싼 수있는 경우 특히, 쓰기 가져 오기 / 설정 방법보다는 사용하여 속성에 의미가 있습니다 그리고 당신은 그것을 강조하고 싶습니다. 그러나 메서드에 대한 PascalCase의 .NET 명명 규칙을 따르고 싶을 것이고 어쨌든 일반적인 메서드로 이와 같은 사소한 속성이 구현되는 것을 원하지 않을 것입니다. 여기서 속성은 훨씬 더 관용적입니다.

C # 6

만세, 마침내 적절한 읽기 전용 자동 구현 속성이 있습니다.

// This can only be assigned to within the constructor
public string Foo { get; }

마찬가지로 일부 작업 을 수행 해야하는 읽기 전용 속성의 경우 멤버 본문 속성을 사용할 수 있습니다.

public double Area => height * width;


답변

일부 데이터를 저장할 변수 만 있으면됩니다.

public string Name { get; set; }

읽기 전용으로 표시 하시겠습니까?

public string Name { get; private set; }

또는 더 나은 …

private readonly string _name;

...

public string Name { get { return _name; } }

속성을 할당하기 전에 값을 확인하고 싶으십니까?

public string Name
{
   get { return m_name; }
   set
   {
      if (value == null)
         throw new ArgumentNullException("value");

      m_name = value;
   }
}

일반적으로 GetXyz () 및 SetXyz ()는 특정 경우에만 사용되며, 옳다고 느껴질 때 직감을 사용해야합니다. 일반적으로 대부분의 get / set 속성은 많은 논리를 포함하지 않고 예상치 못한 부작용이 거의 없을 것으로 예상합니다. 속성 값을 읽는 것은 서비스를 호출하거나 내가 요청하고있어 그 객체를 구축하기 위해 사용자의 입력을 받고 필요한 경우, 나는이 방법으로 포장하고, 같은 호출 것 BuildXyz()보다는, GetXyz().


답변

get / set 메서드가 아닌 C #의 속성을 사용합니다. 그들은 당신의 편의를 위해 거기에 있으며 관용적입니다.

두 가지 C # 예제의 경우 하나는 다른 하나의 구문 설탕입니다. 인스턴스 변수를 둘러싼 간단한 래퍼 만 있으면 auto 속성을 사용하고, getter 및 / 또는 setter에 논리를 추가해야 할 때 전체 버전을 사용하십시오.


답변

C #에서는 get 및 / 또는 set에 대한 개인 필드를 노출하는 속성을 선호합니다. 언급 한 양식은 get 및 set가 숨겨진 피벗 지원 필드를 자동으로 생성하는 자동 속성입니다.

가능한 경우 자동 속성을 선호하지만 C #에서 set / get 메서드 쌍을 수행해서는 안됩니다.


답변

public string Name { get; set; }

이것은 단순히 자동 구현 된 속성입니다. 이며 기술적으로 일반 속성과 동일합니다. 컴파일 할 때 백업 필드가 생성됩니다.

모든 속성은 결국 함수로 변환되므로 결국 실제 컴파일 된 구현은 Java에서 사용하는 것과 동일합니다.

지원 필드에서 특정 작업을 수행 할 필요가없는 경우 자동 구현 속성을 사용합니다. 그렇지 않으면 일반 속성을 사용하십시오. 작업에 부작용이 있거나 계산 비용이 많이 드는 경우 get 및 set 함수를 사용하고 그렇지 않으면 속성을 사용합니다.


답변

C #에서 어떤 방법을 선택하든 최종 결과는 동일합니다. 별도의 getter 및 setter 메서드를 사용하여 backinng 변수를 얻습니다. 속성을 사용하면 모범 사례를 따르므로 원하는 정보를 얼마나 장황하게 볼 수 있는지가 중요합니다.

개인적으로 public string Name { get; set; }가장 적은 공간을 차지하기 때문에 마지막 버전 인 자동 속성을 선택 합니다. 그리고 유효성 검사와 같은 것을 추가해야하는 경우 나중에 언제든지 확장 할 수 있습니다.


답변

가능한 한 string Name { get; set; }간결하고 쉽게 읽을 수있는 공개 를 선호합니다 . 그러나 이것이 필요할 때가 있습니다.

private string name;

public string Name {
   get { return name; }
   set { name = value; }
}