프로퍼티(Property)

프로퍼티는 변수값을 읽거나 쓰는 과정에서 유연한 처리를 삽입할 수 있는 클래스 멤버이다. 클래스 멤버를 설정할 때 필드를 public 으로 설정할지 private 으로 설정할지 고민되는 경우가 많다. 보통 public으로 선언하여 외부 클래스에서 필드에 직접 접근하는 것은 좋은 구조가 아니므로 private으로 선언하지만, 이는 접근 방법이 조금 귀찮아진다. 이렇게 편의성과 은닉성을 동시에 고려할 경우, 프로퍼티는 좋은 선택지가 될 수 있다.

예를 들어 어떤 물체의 길이를 기록하는 클래스를 작성한다고 할때, 길이 데이터를 킬로미터, 센티미터같은 다양한 단위로 변환해서 제공하고자 한다.

public class LengthInfo{
    private float _meters = 0; //미터 단위로 길이 기록

    public float kiloMeters{ //킬로미터 단위로 할당, 반환
        get { return meters * 0.001f;}

        set {
            if(value <= 0){
                _meters = 0;
            }
            else {
                _meters = value * 1000f;
            }
        }
    }
    public float meters{ //미터 단위로 할당, 반환
        get { return _meters;}

        set {
            if(value <= 0){
                _meters = 0;
            }
            else {
                _meters = value;
            }
        }
    }
    public float centiMeters{ //센티미터 단위로 할당, 반환
        get { return meters * 100f;}

        set {
            if(value <= 0){
                _meters = 0;
            }
            else {
                _meters = value * 0.01f;
            }
        }
    }
}

프로퍼티의 get 접근자는 필드의 값을 읽어올때 사용하고, set 접근자는 새 값을 할당할 때 사용한다. 프로퍼티는 변수처럼 보일 수 있지만 특수한 형태의 메서드임을 기억하자.

이제 LengthInfo 오브젝트를 생성하여 물체의 길이를 기록하고 다양한 단위로 출력해보자.

LengthInfo info = new LengthInfo();

info.meters = 35; //meters 의 set 실행
Console.WriteLine(info.kiloMeters + "km"); //kiloMeters의 get실행
Console.WriteLine(info.meters + "m"); //meters의 get실행
Console.WriteLine(info.centiMeters + "cm"); //centiMeteres의 get실행

실행결과
0.035km
35m
3500cm

만약 메서드를 사용하여 멤버 변수에 접근하는 방식을 사용했다면 값을 읽는 메서드, 새로 할당하는 메서드를 단위 마다 다른 경우로 구현해야 했을 것이다. 하지만 프로퍼티를 사용함으로서 비교적 간단하게 구현할 수 있었다.

안전성 증가

프로퍼티는 데이터를 안전하게 다루는 데 도움이 된다. 특히 데이터를 할당하는 처리에 ‘필터’를 추가함으로서 외부에서 잘못된 값을 할당했을 때 내부에서 걸러낼 수 있다.


public float kiloMeters{
        get { return meters * 0.001f;}

        set {
            if(value <= 0){
                _meters = 0;
            }
            else {
                _meters = value * 1000f;
            }
        }
    }

위 코드를 보면 길이가 0보다 작은 값을 가지는 것은 불가능하므로 set 접근자에서 조건문을 통해 0보다 작은 값을 걸러낸다. 이러한 방식으로 잘못된 데이터가 할당될 확률을 줄일 수 있다.

접근자 개별 설정

프로퍼티를 선언할 때 get, set 접근자를 둘 다 써야할 필요는 없다. 읽어오는 기능만 필요하면 get만, 할당하는 기록만 필요하면 set만 사용함으로서 필요에 따라 자유롭게 구성할 수 있다.


public float kiloMeters{
    set {return _meters * 0.001f;}
}
public float meters{
    get {return _meters;}
}

또한, 프로퍼티의 get, set 접근자는 접근 권한을 각각 다르게 부여할 수 있다.

   public float kiloMeters{
        get { return meters * 0.001f;}

        private set {
            if(value <= 0){
                _meters = 0;
            }
            else {
                _meters = value * 1000f;
            }
        }
    }

이럴 경우 외부 클래스에서 kiloMeters의 값을 가져오는 것은 가능하지만 새로운 값을 할당하는것은 불가능해진다.

자동 구현 프로퍼티

만약 get과 set의 접근 권한을 분리하는 것 외의 기능이 필요없다면, 자동 구현 프로퍼티로 간결하게 쓸 수 있다.

public float meters{get; private set;}

위 코드는 아래 코드를 간결하게 자동 생성해주는 것이라 보면 된다.

public float meters{
    get {returm _meters;}
    private set{_meters = value;}
}

태그:

카테고리:

업데이트:

댓글남기기