정신과 시간의 방
카테고리
작성일
2022. 8. 20. 23:12
작성자
risehyun

C#과 유니티로 만드는 MMORPG 게임 개발 시리즈 강의를 수강하며 프로퍼티 파트에서 배우고 느낀 점을 정리해보았다.


  • 프로퍼티의 필요성
    // 객체지향 -> 은닉성
    // 프로퍼티
    class Knight
    {
        protected int hp; // 그렇기 때문에 보통 주요 변수는 보호수준을 높이고

        int GetHp() { return hp; } // 이렇게 getter setter 함수를 이용해서 할당 및 수정 해줄 수 있음.
        public void SetHp(int hp) { this.hp = hp; }

    }

    static void Main(string[] args)
    {

        Knight knight = new Knight();
        knight.hp = 100;

        // 기본 변수 할당 -> 실수로 hp에 접근해서 임의로 값을 변경해버릴 위험이 있음.
        // 이 경우 어디에서 값이 바뀌었는지 알아내기가 어려움.
        knight.hp = 40;

        // 기본 변수 할당의 보완 -> getter setter 함수의 활용
        knight.SetHp(100);
    }

하지만 위의 개선된 코드에도 문제점이 있다. 바로 변수가 늘어나면 getter setter 함수도 그만큼 늘어난다는 것이다.
C++이라면 따로 방법이 없으니 getter setter를 쓰는게 최선이겠지만,

C#에서는 이를 편리하게 해결하기 위한 프로퍼티가 있으니 이를 활용하는 것이 좋다.

  • 프로퍼티 기본형
        public int Hp
        {
            get { }
            set { }
        }

 

  • 사용 예제
        class Knight
        {
            protected int hp;

            public int Hp
            {
                get { return hp; }
                set { this.hp = value; } // 디폴트로 value를 사용함.
            }
        }

        static void Main(string[] args)
        {
            Knight knight = new Knight();
            knight.Hp = 100; // set -> value가 100이 되어 할당됨.

            int hp = knight.Hp; // get -> get함수에서 return 값으로 지정한 변수를 사용하여 가져옴
        }


반드시 get, set 함수가 동시에 사용될 필요가 없기 때문에 경우에 따라 한 쪽 함수만 선언하여 사용하기도 한다.

    class Program 
    {
        class Knight
        {
            protected int hp;

            public int Hp
            {
                get { return hp; }
            }
        }

        static void Main(string[] args)
        {
            Knight knight = new Knight();

            int hp = knight.Hp; // get -> get함수에서 return 값으로 지정한 변수를 사용하여 가져옴
        }
    }

 

또한 get 함수는 외부에 노출해 사용하지만, set함수는 안에서만 사용이 가능하도록 막고 싶을 때의 경우에는 다음과 같이 set 앞에 private 선언을 해주어서 외부 접근이 불가능하도록 만들 수 있다.

        class Knight
        {
            protected int hp;

            public int Hp
            {
                get { return hp; }
                private set { hp = value; }
            }

            void Test()
            {
                Hp = 100;
            }
        }

 

  • 자동화된 프로퍼티
    - 이전의 코드들의 내용을 한 줄로 줄일 수 있는 더욱 간소화된 자동 프로퍼티가 있다.
    // 더욱 간소화된 자동구현 프로퍼티
    class Program 
    {
        class Knight
        {
           public int Hp { get; set; }
            public int Mp { get; set; } = 100; // c# 7.0부터 이처럼 초기화 값을 함께 넣어줄 수 있게 되었음

            // 위의 자동구현 프로퍼티는 아래의 코드 3줄과 같은 의미를 가짐
            private int _hp;
            public int GetHp() { return _hp; }
            public void SetHp(int value) { _hp = value; } 
        }

        static void Main(string[] args)
        {
            Knight knight = new Knight();

            int hp = knight.Hp; // 최종적으로 이렇게 사용할 수 있음
        }

    }

 

[결론]

프로퍼티는 객체지향의 은닉성을 구현하기 위한 수단으로, 외부에서 중요한 내부 변수에 함부로 접근할 수 없게끔 해준다.

또한 프로퍼티는 함수의 형태를 띄고 있지만 public 변수를 접근하고 변경하는 것처럼 편리하게 변수를 다룰 수 있다는 장점이 있다.

따라서 은닉성과 사용의 편리성을 한 번에 챙길 수 있는 문법이라고 할 수 있다.

 

+) 식 본문 멤버

C# 6.0부터 사용할 수 있는 문법 중에는 속성이나 메서드의 Body 블록이 간단한 경우 람다식처럼 사용할 수 있는 식 본문이라는 것이 있다.

프로퍼티를 만들 때 get만 가능한 읽기 전용 프로퍼티를 만들 때 이 식 본문을 활용할 수도 있기에 추가로 학습해 보았다.

 

  • 식 본문 예제
    - 아래의 링크에서 학습한 예제는 다음과 같다. 기존의 람다식처럼 => 기호를 사용하여 입력되는 값 => 반환할 값을 할당해주면 된다.
// 기존의 속성
public int Area
{
    get 
    {
        return Height * Width;
    }
}

// C# 6.0의 Expression-bodied member 표현
public int Area => Height * Width;

 

https://www.csharpstudy.com/CS6/CSharp-Expression-bodied-member.aspx

 

C# 6.0 Expression-bodied - C# 프로그래밍 배우기 (Learn C# Programming)

Expression-bodied member 사용 C#의 속성이나 메서드는 보통 여러 문장(statement)들로 구성된 블럭을 실행하게 된다. 하지만 속성이나 메서드의 Body 블럭이 간단한 경우, Statement Block을 사용하는 대신 간

www.csharpstudy.com

 

'C#' 카테고리의 다른 글

220822 Event (이벤트)  (0) 2022.08.22
[C#] Delegate (대리자)  (0) 2022.08.21
220817 Interface (인터페이스)  (0) 2022.08.17
[C#] 일반화(Generic)  (0) 2022.08.16
220816 배열과 컬렉션  (0) 2022.08.16