独自クラスを文字列として保存する

#独自クラスを文字列に変換する方法
こんにちは。洋梨🍐です。
今回は「データーの保存・復元方法について」です。
アプリ開発などをしていく上で、データーの保存は逃げられない項目です。
今回はそんなデーターの保存を簡単にする方法について書こうと思います。
元の記事は [こちら](https://younaship.com/2019/02/25/%e3%80%90c%e3%80%91%e7%8b%ac%e8%87%aa%e3%82%af%e3%83%a9%e3%82%b9%e3%82%92xml%e5%bd%a2%e5%bc%8f%e3%81%a7%e4%bf%9d%e5%ad%98%e3%81%99%e3%82%8b/) になります。
この記事で分からなかったら参考にしてくださいね！

##保存するクラスを定義
今回は例としてこんな感じのクラスを用意しました。

```C#:
public class UserDATA
{
    public string Name;
    public int Score;
    public float Ave;
    public bool isMen;
}
```
##クラスを文字列として保存する
では配列"UserDATA[]"を文字列に変換していきます。
各自のクラスに対応できるようにジェネリックを使ってます。

※なお、よく使うstring型・int,float,double型しか書いていないので他の型がクラスに入っている場合各自対応してください。(書いていないけどbool,byteなどは一応動く)例えばUnity上のVector3・Colorなどはこのコードだけではそのまま保存できません。
※ Color型 → int R, int G, int B, int A に変換
※ Vector3型　→ float x ,float y, float z に変換してから等...

```C#:
    public string GetFromT(T[] type, string tagName)
    {
        string x = "";
        FieldInfo[] info = typeof(T).GetFields();
        foreach (T t in type)
        {
            x += "<"+tagName+">"
            string s = "";
            for (int i = 0; i < info.Length; i++)
            {
                FieldInfo f = typeof(T).GetField(info[i].Name);
                string addStr = "";
                if (f.GetValue(t) != null) addStr = f.GetValue(t).ToString();
                s += addStr;
                if (i < info.Length - 1) s += ",";
            }
            x += s;
            x += "</"+tagName+">";
        }
        return x;

    }
```
##文字列からクラス配列に戻す
では今度は文字列からクラスに戻していきます。

```C#:
   public T[] GetFromStr(string str, string tagName) // tagName : データーとして扱うタグ名 (例:<a>data</a> -> a)
    {
        Dictionary<string, string> keySet = new Dictionary<string, string>();
        // keySet<string(タグの名前),string(タグで囲まれた文字列)>

        /* ここに文字列から<tagName></tagNeme>で囲まれた文字列をDictionaryに入れていく処理を書く */

        T[] Classes = new T[keySet[tagName].Length];
        int index = 0;
        foreach (string s in keySet[tagName])
        {
            string[] sp = s.Trim().Split(',');
            if (sp.Length != info.Length) throw new System.Exception("No Match Index Count. [" + sp.Length + "]!=[" + info.Length + "]");

            T Class = new T();

            for (int i = 0; i < info.Length; i++)
            {
                FieldInfo f = typeof(T).GetField(info[i].Name);
                if (info[i].FieldType == typeof(int)) f.SetValue(Class, int.Parse(sp[i]));
                else if (info[i].FieldType == typeof(float)) f.SetValue(Class, float.Parse(sp[i]));
                else if (info[i].FieldType == typeof(double)) f.SetValue(Class, double.Parse(sp[i]));
                else if (info[i].FieldType == typeof(string)) f.SetValue(Class, sp[i]);
                else
                {
                    var v = Convert.ChangeType(sp[i], info[i].FieldType);
                    f.SetValue(Class, v);
                }
            }
            Classes[index] = Class;
            index++;
        }
        return Classes;
    }
```

##使用してみる
今回の例"UserDataクラス"の配列を文字列変換してみるとこんな感じになります。
※"tagName"に「P」を指定しています。
![convert_class-xml.png](https://qiita-image-store.s3.amazonaws.com/0/371710/3fb2a868-220b-f1c9-cbda-1d16fcd76bf5.png)
しっかり変換されて保存できてますね。
#まとめ
アプリでこのまま端末に平文保存するのはあまりよくないです。
もっと良い保存方法があるはずなのであくまで参考程度にどうぞ。