작성
·
253
0
public interface ILoader<Key, Value>
{
Dictionary<Key, Value> MakeDict();
}
public class DataManager
{
public Dictionary<int, Data.TestData> TestDic { get; private set; } = new Dictionary<int, Data.TestData>();
public void Init()
{
TestDic = LoadJson<Data.TestDataLoader, int, Data.TestData>("TestData").MakeDict();
}
private Loader LoadJson<Loader, Key, Value>(string path) where Loader : ILoader<Key, Value>
{
TextAsset textAsset = Managers.Resource.Load<TextAsset>(path);
return JsonConvert.DeserializeObject<Loader>(textAsset.text);
}
}
namespace Data
{
#region TestData
...
[Serializable]
public class TestDataLoader : ILoader<int, TestData>
{
public List<TestData> tests = new List<TestData>();
public Dictionary<int, TestData> MakeDict()
{
Dictionary<int, TestData> dict = new Dictionary<int, TestData>();
foreach (TestData testData in tests)
dict.Add(testData.Level, testData);
return dict;
}
}
...
#endregion
}
TestDic = LoadJson<Data.TestDataLoader, int, Data.TestData>("TestData").MakeDict();
DataManager의 위 라인을 실행할 때
TestDataLoader 의 tests 리스트에 값을 담거나 하는 명시된 부분이 없는것 같은데 어떻게 MakeDict(); 가정상적으로 실행될 수 있는것 인가요?
신기해서 이유를 알고싶어 질문 드립니다.
[Serializable]를 명시하면
리턴되는 JsonConvert.DeserializeObject<Loader>(textAsset.text); 의 값이 알맞은 변수에
자동으로 담기는 것인가요?
답변 2
1
[Serializable]은 직렬화 가능하다는 힌트를 남기는 것이고,
JsonConvert가 내부적으로는 Reflection을 이용해 class 구조를 파악하고
그것에 맞게 json 파싱을 시도합니다.
TestDataLoader에는 public List가 있을 것이니 List를 파싱하고 (json 기준으로는 [ ] 이 리스트],
그 List 안에는 TestData가 있는데 이 또한 직렬화 가능한 class이기 때문에
그에 맞게 파싱을 하게 됩니다.
이 모든 것들은 Reflection이라는 우월한 문법 덕분에 가능한 것이죠
0
감사합니다.