C#

[C# 5.0] 프로퍼티

홍성곤 2017. 12. 10. 21:56

1] public 필드의 유혹
: 클래스를 작성하다 보면 필드를 public으로 선언해 버리고 싶은 충동이 들 때가 있다. 무엇보다도, Get/Set 메소드 대신 "="을 사용해서 필드를 읽거나 할당하고 싶은 충동이 일어난다. 
프로퍼티는 이러한 고민을 해결해준다. 편의성과 은닉성 모두 만족시킬 수 있기 때문이다. 

C#을 Java 방식으로 짜면 다음과 같다. 

class MyClass
{
    private int myField;
    
    public GetMyField() { return myField; };
    public void SetMyField ( int NewValue ) { myField = NewValue; };
}

C#은 좀더 편리하게 은닉성을 보존할 수 있는 방법으로 프로퍼티를 제공한다. 


2] 프로퍼티 

1. 선언
class 클래스이름
{
    데이터타입 필드이름;
    접근한정자 데이터타입 프로퍼티이름;
    {
        get
        {
            return 필드이름;
        }
        set
        {
            필드이름 = value;
        }
    }
}

프로퍼티 선언 문법에서 get{}, set{}을 접근자(accessor) 라고 한다. set 접근자 안에 있는 value는 암묵적 매개 변수로 간주한다. 
다음은 위 java 스타일로 작성했던 코드를 다시 프로퍼티를 사용해서 작성해 보겠다. 

class MyClass 
{
    private int myField;
    public int MyField
    {
        get
        {
            return myField;
        }
        set
        {
            myFiled = value;
        }
    }
}

MyClass obj = new MyClass();
obj.MyField = 3;
Console.WriteLine( obj.MyField );

읽기 전용 프로퍼티를 만들고 싶으면 set 접근자를 구현하지 않으면 된다. 
아래와 같이 자동구현 프로퍼티로 구현할 수 있다. 

class BirthdayInfo 
{
    public string Name
    {
        get; set;
    }
    public DateTime Birthday
    {
        get; set;
    }
}

2. 프로퍼티와 생성자
: 객체를 생성할 때 프로퍼티를 이용한 초기화 방법을 사용할 수 있다.

클래스이름 인스턴스 = new 클래스이름()
{
    프로퍼티1 = 값,
    프로퍼티2 = 값,
    프로퍼티3 = 값
}

모든 프로퍼티를 초기화할 필요는 없다. 

BirthdayInfo birth = new BirthdayInfo()
{
    Name = "서현",
    Birthday = new DateTime(1991, 6, 28)
}

3. 무명 타입(Anonymous Type)
: 무명 타입은 타입 정의와 동시에 인스턴스를 만든다. 인스턴스를 만들고 다시는 사용하지 않을때 요긴하다. 

var myInstance = new { Name = "홍길동", Age="17" };

무명 타입에서 주의할 점은 프로퍼티에 할당된 값은 변경 불가하다. 

var a = new { Name = "홍길동", Age = 123 };
Console.WriteLine("Name: {0}, Age: {1}", a.Name, a.Age);

4. 인터페이스의 프로퍼티 

interface IProduct
{
    string ProductName
    {
        get;
        set;
    }
}

class Product: IProduct
{
    private string productName;
    
    public string ProductName
    {
        get { return productName; }
        set { productName = value; }
    }
}

위 코드와 같이 인터페이스의 프로퍼티는 클래스의 자동구현 프로퍼티와 모습이 동일하다. 그리고 인터페이스를 상속받은 클래스는 인터페이스의 모든 프로퍼티를 구현해야 한다. 구현할 때 자동 구현 프로퍼티를 이용해도 된다. 

5. 추상 클래스와 프로퍼티 
: 추상 클래스는 추상 프로퍼티와 일반 프로퍼티를 둘다 가질 수 있다. 그러나 추상 프로퍼티를 인터페이스의 프로퍼티 처럼 선언해 버리면 컴파일러가 자동 구현 프로퍼티로 인식해 버린다. 
그래서 추상 프로퍼티는 "abstract" 키워드를 사용한다. 

abstract class Product
{
    private static int serial = 0;
    public string SerialID
    {
        get { return String.Format("{0:d5}", serial++); }
    }

    abstract public DateTime ProductDate
    {
        get;
        set;
    }
}

class MyProduct : Product
{
    public override DateTime ProductDate
    {
        get;
        set;
    }
}