CodeGym /행동 /C# SELF /C#에서 Properties(속성)

C#에서 Properties(속성)

C# SELF
레벨 17 , 레슨 1
사용 가능

1. 소개

필드를 직접 사용할 때 생기는 문제부터 시작해보자. 만약 네가 public으로 필드를 선언하면, 프로그램 어디서든 바로 값을 바꿀 수 있어:

public class Dog
{
    public string Name;
}

Dog dog = new Dog();
dog.Name = ""; // O_o ... 이건 "강아지 이름 = 빈 문자열"이란 뜻이야!

사용자가 Name 필드에 말도 안 되는 값을 넣을 수 있어. 예를 들면, 빈 문자열, 너무 긴 이름, 아니면 null 같은 거. 이건 마치 누군가 네 새 IKEA 옷장을 조립하는데, 네가 목재 공장 전체를 마음대로 쓰게 해주는 거랑 똑같아.

참고로, 캡슐화란 객체가 자기 데이터를 스스로 관리하는 거야. 내부를 아무나 건드릴 수 없게 하고, 특별한 "문" — property(Properties)를 통해서만 접근하게 하는 거지. 이 문을 통해서 값 체크, 로그 남기기, 값 수정, 기타 반응을 추가할 수 있어.

2. 정의와 문법

Property는 클래스의 특별한 멤버로, 겉보기엔 필드랑 비슷하지만 실제로는 getter(값 가져오기)와 setter(값 설정하기)라는 두 개의 특별한 메서드로 구성돼 있어. property를 사용하면:

  • 데이터 읽기/쓰기를 허용하거나 막을 수 있고,
  • 데이터 접근 시 validation이나 로직을 추가할 수 있고,
  • 내부 필드를 숨기거나, 값을 다른 곳에 저장할 수도 있어.

property 선언은 필드랑 비슷하지만, 중괄호와 get, set 키워드를 써.


[접근_제한자] 타입 Property이름
{
    get { ... }
    set { ... }
}
property 선언 템플릿

우리 Dog 클래스 예시를 보자:

public class Dog
{
    private string _name; // 내부 필드 (private!)

    public string Name
    {
        get { return _name; }  // "getter": 이름 가져오기
        set { _name = value; } // "setter": 이름 설정하기
    }
}

참고: private 필드에는 보통 언더스코어(_name)를 붙여. 이게 C# 스타일 표준이야.

3. property 동작 방식

property는 객체 내부 데이터와 외부 세계 사이에 서 있는 "가드" 같은 존재야. 예시:

Dog dog = new Dog();
dog.Name = "샤릭";
Console.WriteLine(dog.Name);

설명:

  • 프로그램이 dog.Name = "샤릭"; 줄에 도달하면, 이때 property의 set 메서드가 호출돼. 여기서 값이 비어있는지 등 원하는 체크를 추가할 수 있어.
  • Console.WriteLine(dog.Name);에서는 get 메서드가 호출돼서 현재 값을 반환하거나, 필요하면 동적으로 계산해서 반환할 수도 있어.

겉으론 그냥 필드처럼 보이지만, 사실 내부적으로 다 컨트롤되고 있는 거지!

4. 왜 property가 "Best Practice"일까

대부분의 경우, 객체의 내부 필드에 직접 접근을 허용하지 않아. 지금은 체크가 필요 없어 보여도, 데이터를 property로 감싸는 습관이 있으면 나중에 규칙이 바뀔 때 엄청 편해.

값 할당 시 "validation" 예시:


public class Dog
{
    private string _name;

    public string Name
    {
        get { return _name; }
        set
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                throw new ArgumentException("강아지 이름은 비어 있을 수 없어!");
            }
            _name = value;
        }
    }
}

이제 이런 코드는:

dog.Name = ""; // 예외 발생!

… 말도 안 되는 값으로부터 객체를 보호해줘.

5. property: 읽기 전용, 쓰기 전용, 일반 property

가끔은 값 읽기만 허용해야 할 때가 있어(예: 강아지의 출생 연도는 바꿀 수 없어), 또는 반대로 쓰기만 허용해야 할 때도 있어(드물지만 뭔가 신비한 걸 하고 싶을 때).

  • 읽기 전용: get만 쓰고, set은 빼.
  • 쓰기 전용: set만 쓰고, get은 빼.

예시:

public class Dog
{
    private int _birthYear = 2018;

    // 읽기 전용
    public int BirthYear
    {
        get { return _birthYear; }
    }

    // 쓰기 전용 (진짜 드물어)
    public string Secret
    {
        set { /* value로 뭔가 한다 */ }
    }
}

6. property vs 필드

필드 property
문법
public string Name;
public string Name { get; set; }
접근 직접 get/set을 통해
validation 없음 set/get에 추가 가능
확장성 없음 언제든 수정 가능
IDE 통합 필드로 보임 property로 보임(프레임워크에서 중요)

그림: property 동작

sequenceDiagram
participant User as 객체 사용자
participant Dog as Dog 객체
participant Field as private 필드 _name

User->>Dog: dog.Name = "리직"
Dog->>Dog: set Name("리직")
Dog->>Field: _name = "리직"

User->>Dog: print(dog.Name)
Dog->>Dog: get Name()
Dog->>Field: _name 읽기
Dog->>User: "리직" 반환

7. 흔한 실수와 주의점

어디서 실수할 수 있는지 알아보자.

자주 하는 실수 — 필드와 property를 헷갈려서, private 데이터를 실수로 외부에 노출하는 것:

public string name; // 이건 필드야! 어디서나 보임, 위험!

이렇게 하는 게 더 좋아:

private string _name;
public string Name
{
    get { return _name; }
    set { _name = value; }
}

static property도 있는데, 모든 객체에 공통된 값을 저장할 때 써. 하지만 조심해서 써야 해.

재밌는 점: property에 get만 있고 생성자가 하나도 없으면, 값을 아예 바꿀 수 없어 — 이걸 immutable property라고 부르고, 현대 설계에서 많이 써(이건 record랑 불변 데이터 강의에서 자세히 다룰 거야).

2
과제
C# SELF, 레벨 17, 레슨 1
잠금
get과 set 접근이 가능한 프로퍼티 선언하기
get과 set 접근이 가능한 프로퍼티 선언하기
2
과제
C# SELF, 레벨 17, 레슨 1
잠금
입력값 검증이 있는 프로퍼티
입력값 검증이 있는 프로퍼티
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION