HIRASE CONNECTION WK

programming collection

目次

Blog 利用状況

ニュース

書庫

日記カテゴリ

Link Collection

[C#] 自分でオブジェクトをシリアライズ/デシリアライズする。

昨日に続き、実験。XmlSerializerを自前で実装してみます(簡易ですけど)。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml;

namespace Sample
{
    internal class Program
    {

        private static void Main(string[] args)
        {
            MyClass mc = new MyClass();
            mc.Value = "ぴょんぴょん";
            Serialize(mc, @"D:\hoge.xml");
            IEnumerable<Object> deserializedObjects = DeserializeObjects(@"D:\hoge.xml");
            foreach (object deserializedObject in deserializedObjects)
            {
                if (deserializedObject is MyClass)
                {
                    MyClass mc2 = deserializedObject as MyClass;
                    Debug.Assert(String.Equals(mc.Value, mc2.Value));
                }
            }
        }

        /// <summary>
        /// オブジェクトをファイルにシリアライズします。
        /// </summary>
        /// <param name="o">シリアライズするオブジェクト</param>
        /// <param name="filePath">ファイル名</param>
        public static void Serialize(Object o, String filePath)
        {
            using (StreamWriter streamWriter = new StreamWriter(filePath, false, Encoding.UTF8))
            {
                using (XmlWriter xmlWriter = XmlWriter.Create(streamWriter))
                {
                    Type type = o.GetType();
                    xmlWriter.WriteStartElement("class");
                    xmlWriter.WriteAttributeString("type", type.FullName);

                    ForEachPropertyInfo(type, delegate(PropertyInfo propertyInfo)
                        {
                            if (!propertyInfo.CanRead || !propertyInfo.CanWrite)
                                return;

                            Object propertyValue;
                            propertyValue = type.InvokeMember(propertyInfo.Name,
                                                              BindingFlags.GetProperty, null, o, null,
                                                              CultureInfo.CurrentCulture);
                            xmlWriter.WriteAttributeString(propertyInfo.Name, propertyValue.ToString());
                        });
                    xmlWriter.WriteEndElement();
                }
            }
        }

        /// <summary>
        /// ファイルに所定のフォーマットでシリアライズされたデータを
        /// デシリアライズします。
        /// </summary>
        /// <param name="filePath">ファイル名</param>
        public static IEnumerable<Object> DeserializeObjects(String filePath)
        {
            using (StreamReader streamReader = new StreamReader(filePath, Encoding.UTF8, true))
            {
                using (XmlReader xmlReader = XmlReader.Create(streamReader))
                {
                    while (xmlReader.Read())
                    {
                        if (!xmlReader.Name.Equals("class"))
                            continue;

                        String typeName = xmlReader.GetAttribute("type");
                        Type type = Type.GetType(typeName);
                        Object instance = Activator.CreateInstance(type);

                        ForEachPropertyInfo(type, delegate(PropertyInfo propertyInfo)
                            {
                                if (!propertyInfo.CanRead || !propertyInfo.CanWrite)
                                    return;
                                String value = xmlReader.GetAttribute(propertyInfo.Name);
                                type.InvokeMember(propertyInfo.Name,
                                                  BindingFlags.SetProperty, null, instance, new Object[] {value},
                                                  CultureInfo.CurrentCulture);
                            });

                        yield return instance;
                    }
                }
            }
        }

        /// <summary>
        /// 指定した型に含まれるプロパティを全て列挙し、Actionerに渡す。
        /// </summary>
        /// <param name="type">プロパティを列挙したい型</param>
        /// <param name="Actioner">各プロパティを処理するPropertyInfoActioner</param>
        private static void ForEachPropertyInfo(Type type, PropertyInfoActioner Actioner)
        {
            foreach (PropertyInfo propertyInfo in type.GetProperties())
            {
                Actioner(propertyInfo);
            }
        }
        private delegate void PropertyInfoActioner(PropertyInfo propertyInfo);

        #region Nested type: MyClass
        /// <summary>
        /// (テスト用)シリアライズするクラス
        /// </summary>
        private class MyClass
        {
            private String value;

            public String Value
            {
                get { return value; }
                set { this.value = value; }
            }
        }
        #endregion
    }
}

投稿日時 : 2008年3月27日 2:01

コメントを追加

# ksWYQgHaIqjrhwqNbd 2014/08/04 4:30 http://crorkz.com/

p8Km7u Very neat article post. Fantastic.

# GySinsQPpFdFt 2014/09/17 19:36 http://track.oainternetservices.com/doIn?id=505673

I have read some excellent stuff here. Definitely price bookmarking for revisiting. I wonder how so much attempt you place to make one of these wonderful informative website.

# KPymGeoBPpGjKg 2014/09/18 16:19 http://httpdaniel-craig.info/story.php?id=19776

WrKGdy This is one awesome article post.Really looking forward to read more. Awesome.

# Where I can find Ellery Queen 36 ebooks Collection MOBI EPUB To Download? To http://on.hwv.pw/sk 2014/12/15 17:31 FFraARkinb

Diana Peterfreund 9 ebooks Collection MOBI EPUB To Download go to http://v.hwv.pw/ook

タイトル
名前
URL
コメント