이것이 C#이다 9장) 자동구현 Property
프로퍼티
클래스를 작성하다보면 필드를 public으로만 도배하고싶어집니다. 은닉성을 지켜야하기때문에 코드 작성이 귀찮아지죠. 이 은닉성이 신경쓰이므로 우리는 public을 남발 할 순 없습니다. 그렇다면 편의성과 은닉성을 동시에 하는, 두마리의 토끼를 다 잡을 방법은 과연 없는 걸까요? 없을리가 없죠. 바로 이 프로퍼티를 사용한다면 은닉성과 편의성을 즐길 수 있습니다.
[프로퍼티 선언 방법]
class 클래스_이름
{
데이터_형식 필드_이름;
접근_한정자 데이터_형식 프로퍼티_이름
{
get
{
return 필드_이름;
}
set
{
필드_이름 = value;
}
}
}프로퍼티 선언 문법에서 get{ ... }과 set { ... }을 일컬어 접근자(Acessor)라고 한다.
get 접근자는 필드로부터 값을 읽어오고, set 접근자는 필드에 값을 할당합니다.
class MyClass
{
private int myField;
public int MyField
{
get
{
return myField;
}
set
{
myField = value;
}
}
}여기서 읽기 전용(쓰기 불가) 프로퍼티를 원한다면 set { myField = value; }를 제거해주면 됩니다.
하지만 쓰기전용은 쓰지 않는 것을 권장합니다. 코드 관리가 어려워지거든요. 다음은 프로퍼티 예제입니다.
using System;
namespace Property
{
class BirthdayInfo
{
private string name;
private DateTime birthday;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public DateTime Birthday
{
get
{
return birthday;
}
set
{
birthday = value;
}
}
public int Age
{
get
{
return new DateTime(DateTime.Now.Subtract(birthday).Ticks).Year;
}
}
}
class Program
{
static void Main(string[] args)
{
BirthdayInfo birth = new BirthdayInfo();
birth.Name = "무루";
birth.Birthday = new DateTime(1999, 2, 22);
Console.WriteLine($"Name : {birth.Name}");
Console.WriteLine($"Birthday : {birth.Birthday.ToShortDateString()}");
Console.WriteLine($"Age : {birth.Age}");
}
}
}Name : 무루
Birthday : 1999-02-22
Age : 25프로퍼티로 작성해봤는데, 조금 어딘가 긴 느낌이 듭니다.
C#은 더 간편하게 쓸수있게 발전했습니다. 아래 코드를 보시죠.
[자동 구현 프로퍼티 C#]
public class NameCard
{
private string name;
private string phoneNumber;
public string Name
{
get { return name; }
set { name = value; }
}
public string PhoneNumber
{
get { return phoneNumber; }
set { phoneNumber = value; }
}
}
===============================================
[자동 구현 프로퍼티 C# 3.0]
public class NameCard
{
public string Name
{
get; set;
}
public string PhoneNumber
{
get; set;
}
}
===============================================
[자동 구현 프로퍼티 C# 7.0]
public class NameCard
{
private string Name { get; set; } = "이름없음";
private string PhoneNumber { get; set; } = "010-xxxx-xxxx";
}이제는 자동 구현 프로퍼티를 선언함과 동시에 초기화를 수행할 수 있다. 덕분에 자동 구현 프로퍼티에 초깃값이 필요할 때 생성자에 초기화 코드를 작성하는 수고를 덜게된 요즘이다. 막 코딩을 시작하는 나같은 사람에겐 아주 편한 것이었다고...(그래도 잘모르겠음 ..^^) 그렇다면 자동구현 프로퍼티 예제입니다.
using System;
namespace AutoImplementedProperty
{
class BirthdayInfo
{
public string Name { get; set; } = "무루";
public DateTime Birthday { get; set; } = new DateTime(1999, 2, 22);
public int Age
{
get
{
return new DateTime(DateTime.Now.Subtract(Birthday).Ticks).Year;
}
}
}
class Program
{
static void Main(string[] args)
{
BirthdayInfo birth = new BirthdayInfo();
Console.WriteLine($"Name : {birth.Name}");
Console.WriteLine($"Birthday : {birth.Birthday.ToShortDateString()}");
Console.WriteLine($"Age : {birth.Age}");
Console.WriteLine();
birth.Name = "민지";
birth.Birthday = new DateTime(2004, 5, 7);
Console.WriteLine($"Name : {birth.Name}");
Console.WriteLine($"Birthday : {birth.Birthday.ToShortDateString()}");
Console.WriteLine($"Age : {birth.Age}");
Console.WriteLine();
birth.Name = "유진";
birth.Birthday = new DateTime(2003, 9, 1);
Console.WriteLine($"Name : {birth.Name}");
Console.WriteLine($"Birthday : {birth.Birthday.ToShortDateString()}");
Console.WriteLine($"Age : {birth.Age}");
}
}
}Name : 무루
Birthday : 1999-2-22
Age : 25
Name : 민지
Birthday : 2004-5-7
Age : 20
Name : 유진
Birthday : 2003-9-1
Age : 20
C# 데이터 오염방지를 위해 읽기 전용을 하려면 뭐가 있었는지 기억하시나요? 바로 readonly 필드, 구조체, 튜플 등이 있었죠. property는 c# 9.0버전에서 읽기 전용을 쉽게할 수 있도록 개선되었습니다. 바로 'init' 접근자입니다. init 접근자를 명시하는 법을 배워봅시다. 자동 구현 프로퍼티를 선언하며 set 대신 init을 사용해주면 그것이 바로 '초기화 전용 자동구현 프로퍼티'가 됩니다. 예제입니다.
[From: 주는 사람, To : 받는 사람, Amount : 거래량]
using System;
namespace InitOnly
{
class Transaction
{
public string From { get; init; }
public string To { get; init; }
public int Amount { get; init; }
public override string ToString()
{
return $"{From,-10} -> {To,-10} : ${Amount}";
}
}
class Program
{
static void Main(string[] args)
{
Transaction tr1 = new Transaction { From = "주민A", To = "주민B", Amount = 100 };
Transaction tr2 = new Transaction { From = "주민B", To = "주민C", Amount = 50 };
Transaction tr3 = new Transaction { From = "주민C", To = "주민A", Amount = 50 };
Console.WriteLine(tr1);
Console.WriteLine(tr2);
Console.WriteLine(tr3);
}
}
}주민A -> 주민B : $100
주민B -> 주민C : $50
주민C -> 주민A : $50
객체 초기화가 이루어진 지금, 주민B가 주민A에게 빌린 100달러를 다른 금액으로 변경해보자.
초기화 전용 자동 구현 프로퍼티를 수정하려 들면 컴파일 에러가발생한다.
당연하게도 init 접근자는 초기화 이후 발생하는 프로퍼티 수정을 허용하지 않기 때문이다.
아래는 변경 후 결과 값이다.
MainApp.cs(30,13) : error CS885: 초깃값 전용 속성 또는 인덱서
Transaction.Amount 이니셜라이저 또는 'init'접근자 오류