[C#] Public 필드와 프로퍼티

Artiper
|2024. 12. 20. 01:48

Public 필드와 프로퍼티 차이

 

Properties vs. Public Variables

I occasionally see code with properties like this: private int name; public int Name {     get { return name; }     set { name = value; } } As I see it, there are three things to consider here. 1. When is a property not a property? When it's a glor

blog.codinghorror.com

위 글을 번역한 내용이다.

 

C#에서는 아래 코드처럼 프로퍼티를 흔하게 볼 수 있다.

private int name;

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

여기에는 세 가지 고려 사항이 있다고 한다.

 

1. 단순 public 변수로 사용된다면 프로퍼티는 프로퍼티가 아니게 된다.

의미 없는 래퍼 코드로 사람의 시간을 낭비할 필요는 없다. 가장 심플하게 시작은 공용 필드로 해도된다. 나중에 위 name 변수의 값을 수정할 때 추가 작업이 필요하다면 언제든지 이를 프로퍼티로 리팩터링 할 수 있다고 한다. 나는 이와 비슷하지만, 다른 점은 무조건 private 변수로 선언하고, 외부 공개가 필요한 시점에 public으로 변환할 지, 프로퍼티를 사용할지 고민한다.

 

어쨌든, 이 번역 내용의 저자 Jeff Atwood(스택 오버플로 공동 창립자)는 KISS 원칙에 따라 정말 프로퍼티가 필요할 때만 프로퍼티를 사용하라는 것을 주장으로 받아들면된다. 

 

그리고 Jeff의 주장에 대해 지적이 있었던 내용도 살펴보자. 지적을 했던 내용은 위처럼 Name 프로퍼티를 만드는데도 의미가 있다는 주장들이다.

  • 리플렉션이 변수와 프로퍼티에 대해 서로 다르게 동작한다는 점. 리플렉션을 사용하여 모든 프로퍼티를 더 쉽게 사용할 수 있다고 한다.
  • 변수에 대해 데이터 바인딩을 할 수 없다는 점
  • 변수를 프로퍼티로 변경하는 것은 큰 변화라는 점
TryGetTitle(out book.Title); // 변수 필요

 

 

Jeff는 변수와 프로퍼티에 대해 의미 없는 마찰이 너무 많아보인다고 한다. 대부분의 경우 변수와 프로퍼티는 똑같은 일을 하기 때문이라고 하며 두 가지 장점을 모두 누리려면 다음과 같이 사용하면 된다고 한다:

public property int Name;

 

하지만 변수와 프로퍼티의 구분이 이렇게 지속될 정도의 문제라면 좀 더 근본적인 해결책은 없을까? 변수를 완전히 버리고 프로퍼티를 사용하면 안될까? 프로퍼티는 변수와 똑같은 일을 하지만 가독성을 좀 더 세밀하게 제어할 수 있지 않을까라는 기대를 하게 된다.

 

2. 대소문자만 사용하여 public과 private을 구분하는 것은 사고가 터지길 존버하는 것과 비슷하다.

name과 Name의 차이는 정말 근소하다. 대소문자를 사용하여 변수를 구분하는 것은 무책임한 프로그래밍에 가깝다고 한다. m_name, _name과 같이 다르게 보이고 쉽게 보이는 구분 방법을 사용하라고 한다.

 

3. 프로퍼티? 메서드?

이 경우는 프로퍼티가 거의 없다고 한다. 하지만 프로퍼티에서 코드를 실행하는 경우 메서드가 아닌 정말 "프로퍼티"를 작성했는지 확인해라. 프로퍼티는 메서드보다 더 적은 작업을 해야 하고, 가벼워야 한다. 만약 프로퍼티에 상당한 노력이 들어가야 하는 상황이라면 명시적인 메서드로 리팩토링 해야 한다. 그렇지 않으면 프로퍼티의 세팅이 오히려 성가시게 느껴질 수 있다. 그리고 코드가 hourglass(사용자가 대기 신호를 받게 되는 상)를 생성할 가능성이 조금이라도 있으면 반드시 메소드여야 한다고 한다. 반대로 단순하고 가벼운 메서드가 많다면 프로퍼티로 표현해야 할 수 있다. 이는 생각해볼 문제이다.

 

결론

Jeff가 말하고 싶은 정말 중요한 것은 중요하지 않은 코드는 작성하지 않는 것이라고 한다. public 변수를 래핑한 프로퍼티는 정말 의미 없다고 한다.

 

나머지 부분은 변수 이름과 같은 부분은 생동감있도록 구분 가능한 접근 방식을 사용하는 것이 좋다고 한다. 확실하지 않은 경우에는 그냥 Microsfot의 코딩 컨벤션을 따르면 된다. 하지만 .NET 상수를 구식 대문자 방식으로 표현하는 것을 본적이 있어 마음에 걸리는 점이 조금 있기는 하다고 한다.

 

스택 오버플로 내용을 살펴보면 프로퍼티는 진짜 얇은 메서드로 선언되서 해당 값에 브레이크 포인트를 걸 수 있어서 디버깅할 때 좋다고 한다. 이런 점은 필드에 비해 큰 이점이 있다고 생각한다고 한다.

 

또한 그냥 자동 구현 프로퍼티로 만들고 만약 프로퍼티를 lazy-loaded로 변경하고 싶어 프로퍼티에 null 체크를 넣는 것은 정말 쉽지만, 필드를 사용했다면 어셈블리에 누가 무엇을 의존하지는에 따라 다시 컴파일해야 하고 최악의 경우 불가능할 수도 있다고 한다.

 

 

참고 자료