C#のJsonデータを読み書きするためのコードサンプル書きました

#概要

ゲームプログラミングをしていたら思いついたコードです

C#とJson.netで、ゲームデータを読み書きするのにJsonを使うのは、なんか面倒くさかったので、
こういうコードを書いてました
（こういうコードを一から書くのも面倒っていうか）

#注意点

　使用したC#のバージョンは、7.3で、unsafeによるポインタ操作をしています。
更に、Newtonsoft.Json.dllというライブラリも使用してます

#コード

``` csharp
using Newtonsoft.Json.Linq;
using System;

namespace Utility.Json {
	public abstract class JsonData {
		protected JToken Json { get; set; }

		internal JsonData() { }

		public override string ToString() => Json.ToString();

		public JsonData this[string name] {
			get {
				if (Json[name] == null) Json[name] = new JObject();

				return In(name);
			}
		}
		JsonData In(string name) {
			var nested = CreateObj();

			nested.Json = Json[name];

			return nested;
		}
		protected abstract JsonData CreateObj();

		public abstract sbyte? Target(string name, sbyte? value);
		public abstract short? Target(string name, short? value);
		public abstract int? Target(string name, int? value);
		public abstract long? Target(string name, long? value);

		public abstract byte? Target(string name, byte? value);
		public abstract ushort? Target(string name, ushort? value);
		public abstract uint? Target(string name, uint? value);
		public abstract ulong? Target(string name, ulong? value);

		public abstract float? Target(string name, float? value);
		public abstract double? Target(string name, double? value);
		public abstract decimal? Target(string name, decimal? value);

		public abstract bool? Target(string name, bool? value);
		public abstract char? Target(string name, char? value);
		public abstract string Target(string name, string value);

		protected unsafe void SizeError<TNum, TEnum>()
			where TNum : unmanaged
			where TEnum : unmanaged, Enum {

			var numSize = sizeof(TNum);
			var enumSize = sizeof(TEnum);

			if (numSize == enumSize) return;

			var mes = "列挙型 " + default(TEnum).GetType().FullName + " の型サイズが、";
			mes += default(TNum).GetType().FullName + " の型サイズ一致しません\n\n";
			mes += "列挙型の型サイズ : " + numSize + "\n";
			mes += "数値型の型サイズ : " + enumSize + "\n";

			throw new Exception(mes);
		}

		public abstract T? TargetEnum_sbyte<T>(string name, T? value) where T : unmanaged, Enum;
		public abstract T? TargetEnum_short<T>(string name, T? value) where T : unmanaged, Enum;
		public abstract T? TargetEnum_int<T>(string name, T? value) where T : unmanaged, Enum;
		public abstract T? TargetEnum_long<T>(string name, T? value) where T : unmanaged, Enum;

		public abstract T? TargetEnum_byte<T>(string name, T? value) where T : unmanaged, Enum;
		public abstract T? TargetEnum_ushort<T>(string name, T? value) where T : unmanaged, Enum;
		public abstract T? TargetEnum_uint<T>(string name, T? value) where T : unmanaged, Enum;
		public abstract T? TargetEnum_ulong<T>(string name, T? value) where T : unmanaged, Enum;

		public T? TargetEnum_sbyte<T>(string name, T value) where T : unmanaged, Enum {
			return TargetEnum_sbyte(name, (T?)value);
		}
		public T? TargetEnum_short<T>(string name, T value) where T : unmanaged, Enum {
			return TargetEnum_short(name, (T?)value);
		}
		public T? TargetEnum_int<T>(string name, T value) where T : unmanaged, Enum {
			return TargetEnum_int(name, (T?)value);
		}
		public T? TargetEnum_long<T>(string name, T value) where T : unmanaged, Enum {
			return TargetEnum_long(name, (T?)value);
		}

		public T? TargetEnum_byte<T>(string name, T value) where T : unmanaged, Enum {
			return TargetEnum_byte(name, (T?)value);
		}
		public T? TargetEnum_ushort<T>(string name, T value) where T : unmanaged, Enum {
			return TargetEnum_ushort(name, (T?)value);
		}
		public T? TargetEnum_uint<T>(string name, T value) where T : unmanaged, Enum {
			return TargetEnum_uint(name, (T?)value);
		}
		public T? TargetEnum_ulong<T>(string name, T value) where T : unmanaged, Enum {
			return TargetEnum_ulong(name, (T?)value);
		}

		public unsafe T? TargetEnum_signed<T>(string name, T? value) where T : unmanaged, Enum {
			var enumSize = sizeof(T);

			if (enumSize == sizeof(sbyte)) return TargetEnum_sbyte(name, value);
			else if (enumSize == sizeof(short)) return TargetEnum_short(name, value);
			else if (enumSize == sizeof(int)) return TargetEnum_int(name, value);
			else if (enumSize == sizeof(long)) return TargetEnum_long(name, value);

			throw new Exception("出ないと思われるエラー");
		}
		public T? TargetEnum_signed<T>(string name, T value) where T : unmanaged, Enum {
			return TargetEnum_signed(name, (T?)value);
		}

		public unsafe T? TargetEnum_unsigned<T>(string name, T? value) where T : unmanaged, Enum {
			var enumSize = sizeof(T);

			if (enumSize == sizeof(byte)) return TargetEnum_byte(name, value);
			else if (enumSize == sizeof(ushort)) return TargetEnum_ushort(name, value);
			else if (enumSize == sizeof(uint)) return TargetEnum_uint(name, value);
			else if (enumSize == sizeof(ulong)) return TargetEnum_ulong(name, value);

			throw new Exception("出ないと思われるエラー");
		}
		public T? TargetEnum_unsigned<T>(string name, T value) where T : unmanaged, Enum {
			return TargetEnum_unsigned(name, (T?)value);
		}
	}

	public sealed class JsonDataLoader : JsonData {
		public static JsonDataLoader LoadFromText(string jsonStr) {
			return new JsonDataLoader { Json = JToken.Parse(jsonStr) };
		}

		JsonDataLoader() { }

		protected override JsonData CreateObj() => new JsonDataLoader();

		public override sbyte? Target(string name, sbyte? value) {
			return (sbyte?)Json[name];
		}
		public override short? Target(string name, short? value) {
			return (short?)Json[name];
		}
		public override int? Target(string name, int? value) {
			return (int?)Json[name];
		}
		public override long? Target(string name, long? value) {
			return (long?)Json[name];
		}

		public override byte? Target(string name, byte? value) {
			return (byte?)Json[name];
		}
		public override ushort? Target(string name, ushort? value) {
			return (ushort?)Json[name];
		}
		public override uint? Target(string name, uint? value) {
			return (uint?)Json[name];
		}
		public override ulong? Target(string name, ulong? value) {
			return (ulong?)Json[name];
		}

		public override float? Target(string name, float? value) {
			return (float?)Json[name];
		}
		public override double? Target(string name, double? value) {
			return (double?)Json[name];
		}
		public override decimal? Target(string name, decimal? value) {
			return (decimal?)Json[name];
		}

		public override bool? Target(string name, bool? value) {
			return (bool?)Json[name];
		}
		public override char? Target(string name, char? value) {
			return (char?)Json[name];
		}
		public override string Target(string name, string value) {
			return (string)Json[name];
		}

		unsafe TEnum FromNum<TNum, TEnum>(TNum value)
			where TNum : unmanaged
			where TEnum : unmanaged, Enum {

			SizeError<TNum, TEnum>();

			return *(TEnum*)&value;
		}
		unsafe TEnum? FromNum<TNum, TEnum>(TNum? value)
			where TNum : unmanaged
			where TEnum : unmanaged, Enum {

			SizeError<TNum, TEnum>();

			return value.HasValue ?
				(TEnum?)FromNum<TNum, TEnum>(value.Value) :
				null;
		}
		TEnum? FromNum<TNum, TEnum>(TNum? value, TEnum enumType)
			where TNum : unmanaged
			where TEnum : unmanaged, Enum {

			SizeError<TNum, TEnum>();

			return FromNum<TNum, TEnum>(value);
		}

		public override T? TargetEnum_sbyte<T>(string name, T? value) {
			return FromNum(Target(name, default(sbyte?)), default(T));
		}
		public override T? TargetEnum_short<T>(string name, T? value) {
			return FromNum(Target(name, default(short?)), default(T));
		}
		public override T? TargetEnum_int<T>(string name, T? value) {
			return FromNum(Target(name, default(int?)), default(T));
		}
		public override T? TargetEnum_long<T>(string name, T? value) {
			return FromNum(Target(name, default(long?)), default(T));
		}

		public override T? TargetEnum_byte<T>(string name, T? value) {
			return FromNum(Target(name, default(byte?)), default(T));
		}
		public override T? TargetEnum_ushort<T>(string name, T? value) {
			return FromNum(Target(name, default(ushort?)), default(T));
		}
		public override T? TargetEnum_uint<T>(string name, T? value) {
			return FromNum(Target(name, default(uint?)), default(T));
		}
		public override T? TargetEnum_ulong<T>(string name, T? value) {
			return FromNum(Target(name, default(ulong?)), default(T));
		}
	}

	public unsafe sealed class JsonDataSaver : JsonData {
		public static JsonDataSaver CreateRoot() {
			return new JsonDataSaver { Json = new JObject() };
		}

		JsonDataSaver() { }

		protected override JsonData CreateObj() => new JsonDataSaver();

		public override sbyte? Target(string name, sbyte? value) {
			Json[name] = value;

			return value;
		}
		public override short? Target(string name, short? value) {
			Json[name] = value;

			return value;
		}
		public override int? Target(string name, int? value) {
			Json[name] = value;

			return value;
		}
		public override long? Target(string name, long? value) {
			Json[name] = value;

			return value;
		}

		public override byte? Target(string name, byte? value) {
			Json[name] = value;

			return value;
		}
		public override ushort? Target(string name, ushort? value) {
			Json[name] = value;

			return value;
		}
		public override uint? Target(string name, uint? value) {
			Json[name] = value;

			return value;
		}
		public override ulong? Target(string name, ulong? value) {
			Json[name] = value;

			return value;
		}

		public override float? Target(string name, float? value) {
			Json[name] = value;

			return value;
		}
		public override double? Target(string name, double? value) {
			Json[name] = value;

			return value;
		}
		public override decimal? Target(string name, decimal? value) {
			Json[name] = value;

			return value;
		}

		public override bool? Target(string name, bool? value) {
			Json[name] = value;

			return value;
		}
		public override char? Target(string name, char? value) {
			Json[name] = value;

			return value;
		}
		public override string Target(string name, string value) {
			Json[name] = value;

			return value;
		}

		unsafe TNum FromEnum<TNum, TEnum>(TEnum @enum)
			where TNum : unmanaged
			where TEnum : unmanaged, Enum {

			SizeError<TNum, TEnum>();

			return *(TNum*)&@enum;
		}
		unsafe TNum? FromEnum<TNum, TEnum>(TEnum? @enum)
			where TNum : unmanaged
			where TEnum : unmanaged, Enum {

			SizeError<TNum, TEnum>();

			return @enum.HasValue ? (TNum?)FromEnum<TNum, TEnum>(@enum.Value) : null;
		}

		public override T? TargetEnum_sbyte<T>(string name, T? value) {
			Target(name, FromEnum<sbyte, T>(value));

			return value;
		}
		public override T? TargetEnum_short<T>(string name, T? value) {
			Target(name, FromEnum<short, T>(value));

			return value;
		}
		public override T? TargetEnum_int<T>(string name, T? value) {
			Target(name, FromEnum<int, T>(value));

			return value;
		}
		public override T? TargetEnum_long<T>(string name, T? value) {
			Target(name, FromEnum<long, T>(value));

			return value;
		}

		public override T? TargetEnum_byte<T>(string name, T? value) {
			Target(name, FromEnum<byte, T>(value));

			return value;
		}
		public override T? TargetEnum_ushort<T>(string name, T? value) {
			Target(name, FromEnum<ushort, T>(value));

			return value;
		}
		public override T? TargetEnum_uint<T>(string name, T? value) {
			Target(name, FromEnum<uint, T>(value));

			return value;
		}
		public override T? TargetEnum_ulong<T>(string name, T? value) {
			Target(name, FromEnum<ulong, T>(value));

			return value;
		}
	}
}

```

#コードのダウンロード

・ソースのzip（ホームページに移動します）
http://mini09.web.fc2.com/codes/top.html