![[C#] 프로퍼티란? & 자동구현 프로퍼티와 public 변수와의 차이 찾아보기](https://img1.daumcdn.net/thumb/R750x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbqxEA3%2FbtrKwWrlV99%2FSUfKsQdwKIVLBrcIwwYBy1%2Fimg.png)
프로퍼티
사용법을 조금씩 알게되면서 정말 유용하게 사용했던게 프로퍼티였다.
프로퍼티에 대한 이해를 위해 공부한 내용을 정리해봤다.
객체지향 프로그래밍에서는 은닉성을 지키기위해 감춰둔 필드에 접근하기위한 메소드를 만들어 쓴다고한다.
예는 아래 코드와 같다.
private int A;
public int Get_A()
{
return A;
}
public void Set_A(int Value)
{
A = Value;
}
위의 코드는 간단한 예시지만, 다르게 짠다면 바로 필드에 접근하는 것이 아니라 메소드를 통해 다른 안전장치를 걸어 줄수도 있다.
즉 , Class를 설계한 사람의 의도에 맞게 메소드를 통해서만 필드에 접근하도록 한다.
하지만 은닉해야 하는 변수가 한두개가 아니라면 저 메소드들을 하나하나 만들기가 보통 귀찮은 일이 아닐거다.
그래서 C#에서는 이 과정을 간단하게 하기 위한 프로퍼티 라는것을 제공한다.
private int a;
public int A
{
get { return a; }
set { a = value; }
}
은닉해야 할 변수를 Private로 숨기고, 'A'라는 프로퍼티를 선언해 A로만 변수 'a'에 접근할 수 있도록 한다.
value는 A = 10; 이라고 했을때 들어오는 값(10)을 의미한다. 명시적으로 선언하지 않아도 그냥 쓸 수 있다.
처음엔 이걸 왜 쓰는지 잘 몰랐는데 편리하기도 하고,
private int a;
public int A
{
get { return a; }
set
{
if (value < 0)
a = 0;
else
a = value;
}
}
위 코드처럼 set되는 값이 0 보다작다면 그냥 0으로 처리하는 등 .. 여러가지 처리를 할 수 있다.
자동구현 프로퍼티
하지만 또 이렇게 쓰다보면 private로 변수를 선언하고 밑에 public으로 프로퍼티를 선언하고,, 변수가 많아지면 터무니 없이 길어지고 힘든 일이 생긴다.
그래서 C#에서는 자동 구현 프로퍼티라는 기능을 제공한다.
//일반 프로퍼티
private int a;
public int A
{
get { return a; }
set { a = value; }
}
//자동구현 프로퍼티
public int A { get; set; }
굳이 private로 변수를 선언하고 프로퍼티를 만들 필요 없이 옆에 {get; set;} 만 붙여주면 끝이다.
자동구현 프로퍼티는 위와 똑같은 코드라고 하는데, 디컴파일 해보면 private필드가 따로 생긴다고 한다.
[C#] public 필드 vs 자동 구현 프로퍼티 비교 분석 (tistory.com)
(참고 블로그)
Private Set / init

프로퍼티를 만들고 바로 초기화 시켜줄수도 있고,
프로퍼티를 만들때 set앞에 private 접근지정자를 붙여준다면 클래스 내부에서는 set이 되지만 다른 클래스에서는 set을 하려고 했을때 오류를 내는것을 볼 수 있다.
그리고 C# 9.0부터는 프로퍼티의 set부분에 init 키워드를 쓸 수 있다.
init 키워드는 클래스의 생성자에서 초기화 시키거나, 처음 프로퍼티를 생성할때 초기화를 시켜주는것 말고는 set이 불가능하다.
위 사진처럼 클래스 내부에서의 set, 다른 클래스에서의 set이 전부 불가능한것을 볼 수 있다.
public 변수 vs 자동구현 프로퍼티
하지만 늘 의문으로 남았던건 내부적으로 private 필드가 하나 더 생긴다고는 하는데 ,
사용할때 public과 자동구현 프로퍼티의 차이점을 느끼지 못했다.
왜냐하면 private로 변수를 선언하고, 그 변수를 은닉하기 위해 아래에 프로퍼티를 만들어서 어떠한 조건(안전장치)을 걸어 프로퍼티를 사용한다면 프로퍼티를 사용하는 이유가 명확하다고 생각했지만,
//public 필드 변수
public int a;
//프로퍼티
public int A { get; set; }
이 두가지는 내가 사용함에 있어서 기능적으로 다른점을 크게 느끼지 못했다.
그냥 a = 10; / A = 10; 이런식으로 쓰는게 끝이였기 때문이다.
(아마 내가 기능을 많이 쓰지 못했어서 그런거 같다.)
그래서 속이 그렇게 시원하진 않지만 나름대로 한번 자동구현 프로퍼티를 써야하는 이유를 찾아봤다.
인터페이스에서의 차이
인터페이스는 메소드,이벤트, 인덱서, 프로퍼티만을 가질 수 있다.

그래서 인터페이스에 자동구현 프로퍼티를 쓰면 허용하지만,
그냥 일반 변수를 선언한다면 '인터페이스에는 인스턴스 필드가 포함될 수 없습니다' 라는 에러가 뜬다.
오버라이드

프로퍼티는 virtual 한정자를 이용해 상속받은 클래스에서 재정의가 가능하다.
반면에 일반 변수는 virtual 한정자를 허용하지 않는다.

abstract 한정자도 동일하다.
디버깅에서의 차이

C#의 CLR 디버거는 일반 변수의 브레이크 포인트를 지원하지 않는다.
프로퍼티는 가능하다.
Out, Ref 매개변수 한정자의 차이

프로퍼티를 ref 한정자를 이용하여 인수로 넘기면 '속성 또는 인덱서는 out 또는 ref 매개 변수로 전달할 수 없습니다' 라는 오류를 낸다.
readonly 한정자의 차이
생성자에서만 초기화가 가능한 상수와 변수 그 사이 어디인가 쯤 있는 변수를 읽기 전용으로 만드는 한정자 readonly의 사용 가능 유무의 차이가 있다.

프로퍼티는 readonly 한정자를 사용 할 수 없다.
이것저것 정리해봤는데 프로퍼티는 메소드의 성질과 약간 비슷한것같다.

위에 올려둔 블로그에 있는 사진인데 내부적으로 get,set메소드를 만들어내서 그런건가 싶다.
내부적인 정확한 차이를 알진 못하더라도 이번 정리를 통해 어떨때 무엇을 써야할지는 조금 감이 잡히는것같다.
참고 사이트
자동으로 구현된 속성 - C# 프로그래밍 가이드 | Microsoft Docs
자동으로 구현된 속성 - C# 프로그래밍 가이드
C#에서 자동 구현된 속성의 경우 컴파일러는 속성의 get 및 set 접근자를 통해서만 액세스되는 익명의 프라이빗 지원 필드를 만듭니다.
docs.microsoft.com
constructor - What is the best way to give a C# auto-property an initial value? - Stack Overflow
What is the best way to give a C# auto-property an initial value?
How do you give a C# auto-property an initial value? I either use the constructor, or revert to the old syntax. Using the Constructor: class Person { public Person() { Name = "
stackoverflow.com
Properties - C# Programming Guide | Microsoft Docs
Properties - C# Programming Guide
A property in C# is a member that uses accessor methods to read, write, or compute the value of a private field as if it were a public data member.
docs.microsoft.com
'프로그래밍 공부 > C# 프로그래밍' 카테고리의 다른 글
[C#] re-throw? 그리고 throw vs throw EX (2) | 2022.09.18 |
---|---|
[C#] 예외처리 Try - Catch / Throw & Finally (0) | 2022.09.18 |
[C#] 메소드 오버로딩,가변 개수의 인수, 명명된 인수, this() 생성자 (0) | 2022.08.24 |
[C#] ref 와 out 매개변수 한정자 (0) | 2022.08.24 |
[Unity_C#] Switch문 & Switch 식 (0) | 2022.08.21 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!