객체지향 언어라면 은닉성을 지키면서 개발해야 합니다. private, protect 접근 한정자로 내부 데이터를 외부에서 오면 되지 않게 하고, 이 필드에 접근하는 다른 객체에 public get(), public set() 메서드를 따로 제공합니다.
C#도 이 방법을 그대로 사용할 수 있지만, 더 좋은 방법인 프로퍼티를 제공합니다.
솔직히 유니티로 게임을 만들 때 서로 다른 게임 오브젝트 간에 데이터를 읽어오는 작업을 많이 하게 됩니다.
그럴 때마다 은닉성은 개한테 주고 그냥 public으로 선언하고 싶습니다.
물론 게임이 아닌 그냥 클래스를 작성하다 보면 필드를 public으로 선언해버리고 싶은 충동이 들 때가 한두 번이 아닙니다.
데이터가 오염될 수 도 있지만 귀찮습니다.
하지만 프로퍼티를 사용하면 은닉성과 편의성을 모두 지킬 수 있습니다.
기존 C++이나 Java에서는 get(), set() 메서드를 클래스에 추가해서 필드에 접근하도록 했습니다.
물론 이게 C++과 Java에서는 정석이긴 하지만 너무 귀찮고 다른 클래스에 제공되야하는 필드가 많아질수록 더 귀찮습니다.
아래 예시는 클래스에서 필드를 하나 선언하고 get(), set() 메서드를 클래스에 추가해서 MyField에 접근할 수 있게 했습니다
Class MyClass
{
private int myField;
public int GetMyField;
public void SetMyField( int NewValue ) { myField = NewValue; };
}
그리고 이 클래스의 객체는 다음과 같이 사용할 수 있습니다.
MyClass obj = new MyClass();
obj.SetMyfield(3);
Console.WriteLine(obj.GetMyField());
이제는 c#을 공부하니 이 방법보다는 더 우월한 프로퍼티에 익숙해지는 게 좋습니다.
1. 메서드보다 프로퍼티
서두가 좀 길었지만;; 이제 프로퍼티를 선언하는 문법을 보여드리겠습니다. 방법은 아래와 같습니다.
class 클래스이름
{
데이터형식 필드이름;
접근한정자 데이터형식 프로퍼티이름
{
get
{
return 필드이름;
}
set
{
필드이름 = value;
}
}
}
프로퍼티 선언 문법에서 get{....}과 set{...}을 접근자(accessor)라고 합니다.
그리고 여기서 set의 value 키워드를 보면 누구도 선언한 적이 없지만 C# 컴파일러는 set 접근자의 암묵적 매개 변수로 간주하므로 아무 문제를 삼지 않습니다.
그러면 C++의 방식과 비교해 보겠습니다.
class MyClass
{
private int myField;
public int MyField
{
get
{
return myField;
}
set
{
myField = value;
}
}
}
사용은 더 직관적이고 간단합니다.
MyClass obj = new MyClass();
obj.MyField = 3;
Console.WriteLine(obj.MyField);
프로퍼티에서 set 접근자를 구현 안하면 get 접근자만 있게 되어 읽기 전용 프로퍼티가 되고,
get 접근자를 구현 안하면 set 접근자만 있게 되어 쓰기 전용 프로퍼티가 됩니다.
2. 자동 구현 프로퍼티(Auto-Implemented Property)
프로퍼티는 데이터의 오염에 대해선 메서드처럼 안전하고, 데이터를 다룰 때는 필드처럼 간결합니다.
하지만, 필드가 많은 경우 중복된 코드를 메소드보다는 괜찮지만 작성하게 됩니다.
그래서 C# 3.0 때 자동 구현 프로퍼티가 구현되었습니다.
public class NameCard
{
public string Name
{
get; set;
}
public string PhoneNumber
{
get; set;
}
}
필드를 선언할 필요도 없고, 그저 get 접근자와 set 접근자 뒤에 세미콜론(;)만 붙여주면 됩니다.
정말 간단해졌습니다.
여기서 C# 7.0부터는 다음과 같이 자동 구현 프로퍼티를 선언과 동시에 초기화를 수행할 수 있습니다.
덕분에 자동 구현 프로퍼티에 초기값이 필요할 때 생성자에 초기화 코드를 작성하는 수고를 덜게 되었습니다.
public class NameCard
{
public string Name { get; set; } = "Unknown";
public string PhoneNumber { get; set; } = "000-0000-0000";
}
기억하고 있으면 유용하게 사용할 거 같습니다.
공부해도 까먹어서 문제지 저도 까먹어서 제 블로그를 다시 보면서 코딩할 때가 종종 있습니다.
코딩 고수가 되고 싶어요..(┬┬﹏┬┬)
3. 무명 형식(Anonymous Type)
이름 멋있네요 어나니머스 타입
흠흠..
C#에는 여러 가지 형식이 있습니다. 형식에는 이름이 있고요.
int, double, string, FileStream, MyClass 등등
이번 절에서는 이름이 없는 형식, 즉 무명 형식을 설명하려고 합니다.
형식의 이름은 왜 필요할까요?
다음과 같이 그 형식의 이름을 이용해서 인스턴스를 만들기 때문입니다.
int a;
double b;
무명 형식은 형식의 선언과 동시에 인스턴스를 할당합니다.
이 때문에 인스턴스를 만들고 다시는 사용하지 않을 때 요긴합니다.(두 개 이상의 인스턴스를 만들려면 class나 struct를 이용해서 이름을 가진 형식을 별도로 만들어야 합니다.
무명 형식의 선언 예는 아래와 같습니다.
var myInstance = new { Name = "강아지", Age = "2" };
위와 같이 선언한 무명 형식의 인스턴스는 여느 객체처럼 프로퍼티에 접근하여 사용할 수 있습니다.
Console.WriteLine(myInstance.Name, myInstance.Age);
무명 형식에서 주의할 점이라면 값을 변경 못한다는 점입니다.
한마디로 한번 무명 형식의 인스턴스가 만들어지고 난 다음에는 읽기만 가능하다는 이야기입니다.
지금은 이러한 특징들을 보면 무명 형식이 쓸모없어 보이지만 LINQ와 함께 쓰면 아주 요긴하다는 사실을 깨닫게 됩니다.
'C# 프로그래밍' 카테고리의 다른 글
[C#] 컬렉션 초기화 (0) | 2023.02.24 |
---|---|
[C#] 일반화 컬렉션 (0) | 2023.02.23 |
[C#] 컬렉션 (1) | 2023.02.23 |
[C++][C#] 클래스 객체 인스턴스 생성 (0) | 2023.02.22 |
C++, C# 에서 "call by reference" , "pass by reference" (0) | 2023.02.22 |