[C# 5.0] 프로퍼티
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;
}
}