0

作成したリポジトリ クラスで派生クラスを参照しようとしています。

コードは次のとおりです。

[XmlInclude(typeof(Case1))]
[XmlInclude(typeof(Case2))]
[XmlInclude(typeof(Case3))]
public class FileRepo: IFileRepo
{
    public string Name { set; get; }
    public DateTime Time { get; set; }
    public bool Correct{ get; set; }

    public void SerializetoXml(IFileRepo repo)
    {

        var filename = string.Format("{0}__{1}", DateTime.Now.ToString("yyMMddhhss"), "Log.xml");
        var path =
            @"C:\Temp;
        if (!Directory.Exists(path))
            Directory.CreateDirectory(path);
        var fullpath = Path.Combine(path, filename);


        var serializer = new XmlSerializer((typeof(FileRepo))); 
        var textwriter = new StreamWriter(fullpath);

        serializer.Serialize(textwriter, repo);
        textwriter.Close();  
    }
}

基本的に、それぞれに XmlInclude を配置することなく、これらのクラスをすべて「参照」しようとしています。この問題を解決するための例や参考文献を挙げてください。

4

1 に答える 1

2

以下に示すように、「含め」たい型をXmlSerializerコンストラクターに渡すことができます。

public class StackOverflow_15887772
{
    //[XmlInclude(typeof(Case1))]
    //[XmlInclude(typeof(Case2))]
    //[XmlInclude(typeof(Case3))]
    public class FileRepo
    {
        public string Name { set; get; }
        public DateTime Time { get; set; }
        public bool Correct { get; set; }
    }

    public class Case1 : FileRepo { public string Data { get; set; } }
    public class Case2 : FileRepo { public string Data { get; set; } }
    public class Case3 : FileRepo { public string Data { get; set; } }

    public static void SerializetoXml(FileRepo repo)
    {
        MemoryStream ms = new MemoryStream();
        var serializer = new XmlSerializer(typeof(FileRepo), new Type[] { typeof(Case1), typeof(Case2) });
        serializer.Serialize(ms, repo);
        Console.WriteLine("Serialized type {0}:", repo.GetType().Name);
        Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
    }

    public static void Test()
    {
        SerializetoXml(new Case1 { Data = "case 1", Correct = true, Name = "goo", Time = DateTime.UtcNow });
        SerializetoXml(new Case2 { Data = "case 2", Correct = true, Name = "goo", Time = DateTime.UtcNow });
        try
        {
            // this will fail, Case3 isn't passed to the XmlSerializer .ctor
            SerializetoXml(new Case3 { Data = "case 3", Correct = true, Name = "goo", Time = DateTime.UtcNow });
        }
        catch (Exception ex)
        {
            Console.WriteLine("{0}: {1}", ex.GetType().FullName, ex.Message);
            Exception inner = ex.InnerException;
            while (inner != null)
            {
                Console.WriteLine("    {0}: {1}", inner.GetType().FullName, inner.Message);
                inner = inner.InnerException;
            }
        }
    }
}

これが古いことは知っていますが、ここの情報を使用して、次のように機能する汎用メソッドを作成しました。

    public static string toXML<T>(this T obj)
    {
        using (StringWriter writer = new StringWriter())
        {
            XmlSerializer serializer = new XmlSerializer(typeof(T), new Type[] { obj.GetType() });
            serializer.Serialize(writer, obj);
            return writer.ToString();
        }
    }
于 2013-04-08T20:13:50.310 に答える