LoginSignup
1
1

More than 5 years have passed since last update.

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

Last updated at Posted at 2018-10-15

概要

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

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

注意点

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

コード

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

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1