2022. 2. 15. 22:22ㆍLanguages/C#
*이 글은 <유니티 C# 스크립팅 마스터하기> 책을 바탕으로 공부한 글입니다. 문제 시, 삭제하겠습니다.
1. 프로퍼티(Property)
외부에서 어떤 클래스 내부의 변수를 사용할 때, 해당 변수를 이곳 저곳에서 가져가 사용하는 곳에서마다 조건을 보는 것은 비효율적일 수 있습니다. 일반적으로는 다음과 같이 원할 겁니다.
- 변수의 값이 항상 올바르도록 강제하여, 할당된 값을 확실히 하길 바랄 경우
- 예를 들어, 플레이어 체력을 0 ~ 100에만 값 할당하기, 정해진 조합만을 허용하는 문자열 변수 만들기 등
- 변수의 값이 변경되었을 때를 감지하여, 이 값에 영향을 받는 다른 함수나 동작을 실행하길 원할 경우
이에 활용할 수 있는 것이 바로 프로퍼티(Property)입니다.
2. 프로퍼티의 사용 예시
1) 정해진 범위 내의 값만 할당하기
대략적인 사용 예시 형태는 다음과 같습니다.
public class Example : MonoBehaviour
{
public float HP // '_hp' 변수에 대한 프로퍼티
{
get
{
return _hp;
}
set
{
if(_hp >= 0f && _hp <= 100f)
{
_hp = value;
}
}
}
private float _hp; // 실제 내부 클래스 변수
}
- 변수처럼 선언되지만, 함수처럼 중괄호로 묶이는 것이 특징
- get : 외부에서 해당 프로퍼티에 접근하여 읽어야 하는 상황에서 호출됨
- set : 외부에서 해당 프로퍼티에 접근하여 값을 할당하는 상황에서 호출됨
위와 같이 프로퍼티의 set 함수에 조건부로 값을 할당받는 코드를 작성하면, 외부에서 해당 프로퍼티를 통해 변수에 값을 할당할 때 별도의 조건문이 필요없게 됩니다.
Example example = new Example();
example.HP = 10f; // 올바른 값 할당
// example.HP = 5000f; 값이 할당되긴 하나, 프로퍼티 내부에서 필터링된다.
2) 특정 이벤트 발생시키기
변수의 값 변경 이벤트를 발생시키길 원한다면 프로퍼티를 통해서도 구현이 가능합니다.
public float HP
{
get
{
return _hp;
}
set
{
if(_hp >= 0f && _hp <= 100f)
{
float preHp = _hp;
_hp = value;
if (!Mathf.Approximately(_hp, preHp))
OnChangeValue();
}
}
}
3. 프로퍼티의 종류
읽기 전용 프로퍼티
public class Example : MonoBehaviour
{
private float _hp;
public float HP // 읽기 전용
{
get
{
return _hp;
}
}
}
쓰기 전용 프로퍼티
public class Example : MonoBehaviour
{
private float _hp;
public float HP // 쓰기 전용
{
set
{
_hp = value;
}
}
}
자동 구현 프로퍼티
- 조건이 있는 것이 아닌, 단순히 변수 값 할당과 반환만 할 것이라면 자동 구현 프로퍼티 사용이 편함.
- get, set 접근자 안에 아무것도 쓰지 않으면 됨.
- 클래스 내부 변수에 대한 할당, 반환이 아닌 프로퍼티 그 자체를 사용하는 것.
public class Example : MonoBehaviour
{
public float HP { get; set; } // 자동 구현 프로퍼티
}
class ExternalClass
{
public void Function()
{
Example example = new Example();
example.HP = 50f; // 프로퍼티 그 자체를 변수로 사용한다.
}
}
프로퍼티 사용 팁
// 1. 프로퍼티는 선언과 동시에 필드에 대한 초기화 가능
public float HP { get; set; } = 100f;
// 2. 클래스 객체를 생성할 때도 초기화 가능
Example example = new Example() { HP = 100f };
// 3. 무명 형식 지원
var example = new { HP = 100f }; // 단, 한번 값 할당하면 변경 불가
초기화 전용 자동 구현 프로퍼티
C# 9.0에 도입된 기능으로, 기존에는 프로퍼티를 읽기 전용으로 선언하는 방법이 불편하였습니다.
생성자를 통해 필드를 초기화하고, 그 필드에 접근하는 프로퍼티는 get 접근자만 갖도록 해야 했죠.
// 기존 방식
class Monster
{
private string name;
private int hp;
private int damage;
public Monster(string name, int hp, int damage)
{
this.name = name;
this.hp = hp;
this.damage = damage;
}
public string Name { get {return name;} }
public int HP { get {return hp;} }
public int Damage { get {return damage;} }
}
이런 불편함은 자동 구현 프로퍼티에 init 접근자를 사용하면서 해결할 수 있습니다. set 접근자처럼 외부에서 프로퍼티를 변경할 수 있지만, 객체 초기화를 할 때만 가능하다는 점이 set 접근자와의 차이점입니다.
// 초기화 전용 자동 구현 프로퍼티
class Monster
{
public string Name { get; init; }
public int HP { get; init; }
public int Damage { get; init; }
}
객체 생성 후, 해당 프로퍼티 내용을 수정하려고 하면 컴파일 오류가 발생하게 됩니다.
Monster monster = new Monster
{
Name = "Slime",
HP = 500,
Damage = 10
};
// monster.HP = 1000; 컴파일 오류. 초기화 후 수정 불가
// 오류 메시지
"초깃값 전용 속성 또는 인덱서 "Monster.HP"은(는)
개체 이니셜라이저 또는 인스턴스 생성자나
'init' 접근자의 'this' 또는 'base'에만 할당할 수 있습니다."
4. 인터페이스와 추상 클래스의 프로퍼티
인터페이스 프로퍼티
인터페이스이므로 구현부는 갖지 않고, 인터페이스를 상속받는 클래스에서 반드시 해당 프로퍼티를 구현해야 합니다.
interface IMonster
{
string Name // 자동 구현 프로퍼티와 똑같이 생겼지만 컴파일러가 자동으로 구현해주지 않음
{
get;
set;
}
}
class Monster : IMonster
{
private string name;
public string Name // 자식 클래스는 기반 인터페이스에 선언된 모든 프로퍼티를 구현해야 함
{
get {return name;}
set {name = value;}
}
}
추상 클래스의 추상 프로퍼티
추상 클래스는 클래스처럼 구현된 프로퍼티를 가질 수도 있지만, 인터페이스처럼 구현되지 않은 프로퍼티도 가질 수 있습니다. 이것을 추상 프로퍼티(Abstract Property)라고 합니다.
abstract class AbstractMonster
{
public int HP { get; set;} // 자동 구현 프로퍼티
abstract string Name // 추상 프로퍼티
{
get;
set;
}
}
class Monster : AbstractMonster
{
public override string Name // 추상 프로퍼티 재정의 강제
{
get;
set;
}
}
'Languages > C#' 카테고리의 다른 글
[C#] TryParse() VS Parse() (0) | 2022.03.13 |
---|---|
[C#] Null과 관련된 연산자들(?, [ ]?, ??) (0) | 2022.03.13 |
[C#] 문자열 서식 맞추기 (string.Format(), 문자열 보간) (0) | 2022.03.09 |
[C#] Nullable (0) | 2022.03.09 |
[C#] CLR(Common Language Runtime)과 네이티브 코드(Native Code) (0) | 2022.03.09 |