내일배움캠프 3주차 3일차 TIL - 프로퍼티 파헤치기

백흰범·2024년 5월 1일
0

오늘 한 일

  • 팀 프로젝트 스킬 기능, 레벨업 기능 및 레벨 보상 구현하기

프로퍼티 파헤치기 (Microsoft Learn 속성 사용)

프로퍼티에서 주로 쓰이는 형태

    int field;    // 프로퍼티의 저장소 

    public int Property // 프로퍼티
    {
        get { return field; }
        private set
        {
        field = value;
        }
    }
  • 프로퍼티는 위와 같이 특정 필드(클래스의 변수)의 읽기(get)와(과) 할당(set)을 대신 담당해줄 수 있는 역할로 자주 쓰인다. 특히 get과 set에 원하는 코드를 추가시켜서 데이터의 유효성을 검사하거나 특정 이벤트를 발생시키는 등 컴파일러가 허락한 선 내에서는 마음껏 커스터마이징이 가능하다.

프로퍼티의 활용법

  • 다수의 필드를 할당
  class Player
  {
      int Atk;
      int Def;
      int Hp;

      public int PlayerAllStatUp
      {
          get 
          {
              return 0;   // 단체로 반환하기에는 좀 힘들다;
          }
          private set // 해당 set을 보면 플레이어의 스텟을 전부 건들고 있다.
          {
              Console.WriteLine($"공격력 : {Atk} -> {Atk + value}!");
              Console.WriteLine($"방어력 : {Def} -> {Def + value}!");
              Console.WriteLine($"체력 : {Hp} -> {Hp + (value * 10)}!");
              Atk += value;
              Def += value;
              Hp += value * 10;
          }
      }

      public void Levelup(int statup)	// 레벨업과 추가시켜줄 스텟
      {
          Console.WriteLine("레벨이 올랐습니다!");
          PlayerAllStatUp = statup;
      }
  }
  • 실행 결과

  • 메서드 호출 (이벤트, Action 등등)
      int exp;
      int lv;

      public int Exp
      {
          get { return exp; }
          set
          {
              exp = value;
              while (exp >= lv * 5)	// 왜 이렇게 했는지는 흐름을 보면 알 수 있다. (while은 조건문이자 반복문이다.)
              {
                  exp -= lv * 5;
                  lv++;
                  Levelup();
              }
          }

      }
    
     void Levelup()
     {
         Console.WriteLine($"레벨이 올랐습니다! {lv-1} -> {lv}");
         PlayerAllStatUp = 5;
     }
  • 실행 결과

표현식 본문을 활용해서 프로퍼티 좀 더 간단하게 선언하기

// 읽기 전용
      string name;
      public string Name => name;	// 여기서 표현식 본문은 => 를 의미한다.
// 쓰기 전용
	  string name;
      public string Name
      {
      	get => name;
        set => name = value;
      }
  • 딱히 큰 기능은 없고 보호 수준 때문에 단순히 설정하는 거라면 위와 같이 설정해줘도 된다. (팀원 분들과의 합의를 통해서)

자동 프로퍼티

    public int AutoProperty { get; set; } // 자동 구현 프로퍼티
  • 위와 같은 경우에는 AutoProperty가 변수인 동시에 프로퍼티 역할을 하는 셈이 된다. 딱히 기능을 추가할 필요가 없는 필드(클래스 변수)인 경우에는 위와 같이 설정해두는 편이 좋다.

! 프로퍼티를 사용할 때 주의할 점

  • 기본 프로퍼티와 자동 프로퍼티를 혼동하면 안된다.

    • 만약에 기본 프로퍼티를 자동 프로퍼티와 동일하다는 생각을 하고 프로퍼티를 작성하게 되면은..
      public int Property // 잘못된 프로퍼티
      {
          get { return Property; }
          private set
          {
              Property = value;
          }
      }
  • 위와 같은 형태로 작성하게 될텐데, 이 경우 접근 또는 할당을 시도하려고 할 경우에는...
  • 위와 같이 Stack overflow가 발생한다.
    위와 같은 현상이 발생하는 이유는 일단 rtan.Property 코드에서 Property를 읽기 위해 get 메서드를 호출하게 되면 get의 실행문이 실행되는데 문제는 실행문에 안에 있는 Property를 접근하면 또다시 Property를 실행하게 되서 무한 호출에 걸려 스택 오버플로우가 발생하는 것이다... (이러면 왜 자동 프로퍼티의 형태가 { get; set; }의 형태인지 이해하게 될 것이다)

  • 프로퍼티로 메서드를 호출해서 상호작용할 때 백업 저장소의 이름과 헷갈리지말자.

    • 만약에 프로퍼티에 메서드를 호출하는 게 있는데 그 메소드가 백업 저장소를 활용할 경우 네이밍에 좀 유의해야할 것이다.
// 혼동된 사용의 예시
```c
      int exp;
      int lv;

      public int Exp
      {
          get { return exp; }
          set
          {
              exp = value;
              Levelup();
          }
      }
    
     void Levelup()
     {
     	  while (exp >= lv * 5)	
          {
              Exp -= lv * 5; 	// 여기서 Exp를 쓰면 또 다시 LevelUp() 메서드를 호출하게된다. 
              					// (Exp와 exp가 엄연히 다른 역할을 한다는 걸 잊지 말자!)
              lv++;
         Console.WriteLine($"레벨이 올랐습니다! {lv-1} -> {lv}");
         PlayerAllStatUp = 5;
         }
     }
  • 실행 결과
  • 안 그래도 while 문 때문에 무한히 반복되었다.
    • 반복의 이유는 lv++이 되기전에 자꾸 Exp가 exp가 0이 감소된 채로 무한히 호출하게 되어서 생기는 문제다.

버그 나는 거 알아보겠다고 디버그창 자체에 문제가 생기는 버그를 자주 실행하면, 디버그창이 삐져서 다시 안 나오는 경우가 있으니 유의하자.


오늘 작성하면서 느낀점

내가 기존에 배웠던 지식이 내가 정말 이 지식을 잘 알고 있는가에 대한 의심은 끊임없이 이뤄져야만 하는 것 같다. 내가 어떠한 지식을 안다라는 개념이라는 게 그 안다에서도 스펙트럼의 차이가 갈리고 그 안다의 차이로 인해 어떻게 활용되느냐에 따라서 많이 갈리는 것 같다. 그만큼 가지고 있는 지식을 자주 회고하고 다뤄줘야만 그 지식의 활용도를 높일 수 있는 좋은 방법이라고 생각한다.

profile
게임 개발 꿈나무

0개의 댓글