Getter, Setter
들어가는 말
클래스의 멤버 변수를 private 접근 제어자(Access Modifier)로 선언하면 외부에서 멤버 변수에 직접 접근할 수 없다.
이를 통해 내부 구현을 숨기고 데이터를 보호하는 정보 은닉(Information Hiding)을 구현할 수 있다.
하지만 이로 인해 외부에서 값을 읽거나 수정할 수 있는 방법이 사라진다.
이 글에서는 이러한 문제를 해결하기 위한 getter, setter 함수에 대해 전통적인 방법부터 C#에서 제공하는 방식을 알아보자.
1. 함수를 이용한 전통적인 방식
get은 “가져오다”라는 의미의 동사이고, set은 “설정하다”라는 의미의 동사이다.
-er는 동작을 수행하는 주체를 나타내는 접미사다.
따라서 Getter는 “값을 가져오는 역할을 하는 것”, Setter는 “값을 설정하는 역할을 하는 것”이라는 의미다.
Getter와 Setter는 별도의 특별한 문법이 아니라 단순한 메서드로 구현된다.
이 방식은 특정 언어에 종속되지 않으며, 어떤 객체지향 언어에서도 동일하게 사용할 수 있다.
public class Box
{
private int _size;
public Box(int size)
{
SetSize(size);
}
public int GetSize()
{
return _size;
}
public void SetSize(int size)
{
if (size <= 0)
throw new ArgumentException("Size must be greater than 0.");
_size = size;
}
}
Box box = new Box(5);
Console.WriteLine(box.GetSize()); // 5
box.SetSize(10);
Console.WriteLine(box.GetSize()); // 10
box.SetSize(-1); // ArgumentException thrown
메서드 이름은 예제처럼 GetSize, SetSize 형태로 작성할 수도 있고, getSize, setSize처럼 작성할 수도 있다.
이는 언어나 팀의 코딩 컨벤션에 따라 달라지며, 문법적으로 강제되는 부분이 아니다.
1-1. 문제점: 반복적이고 장황한 코드
이 방식은 필드 하나마다 Getter와 Setter 메서드를 각각 작성해야 한다.
IDE의 자동 생성 기능으로 쉽게 만들 수 있지만, 필드가 하나 추가될 때마다
두 개의 메서드가 함께 추가되어 클래스 파일의 코드가 점점 길어진다.
이러한 문제를 해결하기 위해 프로그래밍 언어 또는 라이브러리 차원에서 다양한 방법이 제공된다.
2. C# 프로퍼티
C#은 getter/setter 패턴을 프로퍼티(Property) 문법으로 제공한다.
프로퍼티를 사용하면 마치 필드처럼 값에 접근할 수 있으면서, 실제 내부적으로는 정의된 getter와 setter 메서드를 통해 읽기/쓰기 동작이 수행된다.
2-1. Full Property (C# 1.0, 2002)
값을 실제로 저장하는 _size 같은 필드를 backing field라고 부르며, 프로퍼티는 이 값을 읽고 설정하는 역할을 한다.
value는 setter에 전달되는 암시적(묵시적) 매개변수다.
public class Box
{
private int _size; // backing field
public int Size
{
get { return _size; }
set
{
if (value <= 0)
throw new ArgumentException("Size must be greater than 0.");
_size = value;
}
}
public Box(int size)
{
Size = size;
}
}
Box box = new Box(5);
Console.WriteLine(box.Size); // 5
box.Size = 10;
Console.WriteLine(box.Size); // 10
box.Size = -1; // ArgumentException thrown
2-2. Auto-implemented Property (C# 3.0, 2007)
getter/setter에 별도 로직이 필요 없다면, backing field 선언 없이 간략하게 작성 할 수 있다.
내부적으로 컴파일러가 자동으로 backing field를 생성하지만, 프로그래머가 직접 접근할 수는 없다.
public class Person
{
public string Name { get; set; };
}
Person p = new Person();
p.Name = "Tom";
Console.WriteLine(p.Name); // "Tom"
2-3. Field Backed Property (C# 14, 2025)
기존 두 가지 방식에는 각각 아쉬운 점이 있다.
Full Property는 로직을 추가할 수 있지만 backing field와 프로퍼티를 선언해야 해서 코드가 길어진다.
Auto-implemented Property는 간결하지만 로직을 추가할 수 없다.
field: 컴파일러가 생성한 backing field에 접근하는 키워드value: setter에 전달되는 암시적 매개변수
public class Person
{
public string Name
{
get;
set => field = value.Trim();
}
}
Person p = new Person();
p.Name = " Tom "
Console.WriteLine(p.Name); // "Tom"
2-4. 차이점 정리
| 방법 | 필드 선언 | 로직 추가 | 코드 길이 |
|---|---|---|---|
| Full Property | 수동 | 가능 | 김 |
| Auto-implemented Property | 자동 | 불가능 | 짧음 |
| Field-backed Property | 자동 | 가능 | 짧음 |