목차
Console 활용, [JsonConstructor]
벌써 수요일이군... 시간 참 빠르다.
Console 활용
Console.OutputEncoding = Encoding.UTF8;
Console.WriteLine(new string('=', Console.WindowWidth));
어제 TIL에 올렸어야 했는데 깜빡했다!
늘 수동으로 ============================= 을 찍었는데 Console.WindowWidth로 콘솔 가로폭에 맞춰서 찍을 수 있다.
또한 특수문자를 출력하려면, Encoding 출력을 UTF8로 설정해주어야함.


[JsonConstructor]
이전 개인 과제와, 현재 팀 과제의 프로퍼티 설정이 조금 다르다.
하나로 맞추고 싶었고, 팀원들이 공통적으로 이해하기 쉽다고 생각하는 방법으로 읽기 전용 프로퍼티를 다음과 같이 만들었다.
public JobType JobType { get; private set; }
public Inventory Inventory { get; private set; }
public uint NumOfStones { get; private set; }
그러다보니 [JsonProperty]로도 역직렬화가 불가능해졌다.
[JsonProperty]는 private 혹은 protected 프로퍼티만 직렬화, 역직렬화가 가능하게 하고,
public 필드의 {get, private set}의 경우에는 직렬화는 잘 되지만, 역직렬화가 불가능하다.
(이전에 레딧에서 찾은 해결법에는 private set을 역직렬화할 수 있다고 했던 것 같은데 실제로 해보니까 안되서 당황;;)
그래서!
[JsonProperty] 설정을 사용하는 private 필드를 전부 만들고,
[JsonIgnore] 설정을 public 프로퍼티에 전부 적용을 했.었.다!
하지만 커밋할때 지옥의 충돌 해결을 해야할 것 같아서... 더 좋은 방법을 찾아봤다!
역직렬화 전용 생성자만 만들어주면 되는 [JsonConstructor]를 써봤다.
필요한 모든 필드를 생성자 파라미터로 받아서 초기화하면 된다.
다만, 내부에 내부에 복합 개체 (가벼운 참조 하는 녀석들)은 Clone() 메서드를 통해 복사 처리하는 것이 좋다.
[JsonConstructor]가 지정된 생성자는 역직렬화시 기본 생성자보다 무조건 우선적으로 호출된다.
[JsonConstructor]
public Player(
uint id,
string name,
uint hp,
/* 중략 */
Inventory inventory,
uint gold,
uint exp
) : base(name)
{
Console.WriteLine("Player 역직렬화 생성자");
this.Id = id;
this.Name = name;
this.HP = hp;
/* 중략 */
this.Inventory.Clone(inventory);
this.Gold = gold;
this.Exp = exp;
}
참고로, [JsonProperty] 없이도 역직렬화하려면 생성자 파라미터 이름이 Json 키 이름과 정확히 일치해야한다.
Newtonsoft.Json은 대소문자 구분을 하지 않는다.
또한 key 값을 사용하기 때문에 속성의 순서 또한 무시한다.
하지만 불안하다면 [JsonProperty]로 key 값을 수동으로 설정하는 것도 좋은 방법일 것 같다.
이 경우에는 괜히 또 무언가 건드렸다가 에러가 날까봐 그냥 잘 되는 상태로 두었다.
추상 클래스를 상속 받는 개체에 [JsonConstructor]를 쓰려면?
이미 위에 올린 코드처럼, 부모 클래스의 생성자를 base로 명시적으로 호출하는 경우 부모 추상 클래스에서도 [JsonConstructor]를 설정해주어야 한다. (지금 보니.. 명시적 호출 빼고 추상클래스에 [JsonConstructor] 설정 안해도 됬을 듯)
[JsonConstructor]
public Character(
uint id,
string name,
uint hP,
uint mP,
uint attack,
uint defense)
{
this.Id = id;
this.Name = name;
this.HP = hP;
this.MP = mP;
this.Attack = attack;
this.Defense = defense;
}
저장에 에러가 났다면? 체크리스트
Json을 쓰면서 에러가 날 때마다 우왕좌왕 이곳저곳을 건드리느라 시간이 많이 소모되는 것을 느꼈다.
이번 문제 해결들을 하면서 Json 문제가 생겼을 때 순서대로 따라가는 체크리스트를 정리했다.
- 저장 경로와 파일 이름
- 저장하는 경로가 올바른지, 파일 생성 여부를 통해 확인.
- 되도록 path는 string으로 저장하여 하드코딩하는 것을 피하는 것이 좋다.
- 저장 직전 데이터 준비
- 데이터를 담은 객체가 제대로 준비 되어있는지 확인.
- 해당 객체의 변화를 디버깅으로 확인하거나 Console.WriteLine으로 체크.
- 직렬화 설정
- Json 직렬화 설정이 적절한지 확인한다.
- [JsonProperty]와 같은 설정들 & 커스텀 컨버터가 제대로 되어있는지.
- 생성된 파일을 열어보고 내용을 비교하여 확인할 수 있다.
- 불러오기 시 파일 존재 여부
- 존재하지 않는 파일일 경우 예외 처리 필요.
- 불러온 데이터 역직렬화
- Json 에서 객체로 변환이 제대로 되는지 확인.
- 역직렬화 된 객체 내부 필드 (오브젝트 들)은 null로 불러와지진 않는지 확인
- 해당 객체의 변화를 디버깅으로 확인하거나 Console.WriteLine으로 체크.
- 역직렬화된 객체에서 다른 객체나 리스트 등의 참조가 잘 연결되었는지 확인한다.
일단 내가 직접 경험 해본 경우들 + 내 예상들로만 정리된 것이라 다른 에러가 발생할 수도 있지만,
이 전에 겪어봤던 문제들은 빠르게 체크할 수 있을 것 같다.
느낀점
하... json.. 진짜 싫다...... 그치만 제대로 작동하면 그만큼 짜릿한게 없다.
Unity Json 활용은 더 날 것이라고 들었는데... newtonsoft야 unity json도 개발해주지 않겠니? (찾아보니 plugin으로 사용한다고함)
내일 학습 할 것은 무엇인지
오늘 세이브 로드 데이터 때문에 던전 구현을 거의 하지 못했다.
=> 금방 구현했다!
코드리뷰를 하지 못했는데... 내일 스크럼... 어쩌지...
'부트캠프 > 본캠프' 카테고리의 다른 글
| [내일배움캠프_2025JUL18] 콘솔 입력 버퍼 (0) | 2025.07.18 |
|---|---|
| [내일배움캠프_2025JUL17] 화살표 선택 메뉴 틀 구현, 개발 가이드라인 문서 작성, 패턴 매칭 (Pattern Matching) (0) | 2025.07.17 |
| [내일배움캠프_2025JUL15] 스크럼 마스터, 스킬 구현, 그 놈의 JSON (0) | 2025.07.15 |
| [내일배움캠프_2025JUL14]팀 과제 시작! (0) | 2025.07.14 |
| [내일배움캠프_2025JUL13]TextRPG 팀 과제 구조 설계 & Today I Reflected... (0) | 2025.07.13 |