26

重複の可能性:
XML-Serializable クラスにパラメーターなしのコンストラクターが必要な理由

コードでタプルをシリアル化しようとしています:

List<List<Tuple<String, CodeExtractor.StatementNode>>> results = null;
results = extractor.ExtractSourceCode(sourceCode);
FileStream fs = new FileStream(@"C:\Projects\Test\ast.xml", FileMode.Create);

XmlSerializer formatter = new XmlSerializer(
    typeof(List<List<Tuple<String, CodeExtractor.StatementNode>>>));

formatter.Serialize(fs, results);

fs.Close();

しかし、それは失敗し、次のような例外をキャッチしました:

System.Tuple`2[System.String,CodeExtractor.StatementNode] は、パラメーターなしのコンストラクターがないため、シリアル化できません。

CodeExtractor.StatementNodeシリアル化できると確信しています。

4

2 に答える 2

34

そのXmlSerializer仕事をすることができるために、それはデフォルトの建設業者を必要とします。これは、引数をとらないコンストラクターです。すべてのTuple<...>クラスには単一のコンストラクターがあり、そのコンストラクターはいくつかの引数を取ります。タプルの値ごとに1つ。したがって、あなたの場合、唯一のコンストラクタは

Tuple(T1 value1, T2 value2)

シリアライザーは引数のないコンストラクターを探していますが、コンストラクターが見つからないため、例外が発生します。

シリアル化の目的でタプルの代わりに使用できる可変クラスを作成できます

class MyTuple<T1, T2>
{
    MyTuple() { }

    public T1 Item1 { get; set; }
    public T2 Item2 { get; set; }

    public static implicit operator MyTuple<T1, T2>(Tuple<T1, T2> t)
    {
         return new MyTuple<T1, T2>(){
                      Item1 = t.Item1,
                      Item2 = t.Item2
                    };
    }

    public static implicit operator Tuple<T1, T2>(MyTuple<T1, T2> t)
    {
        return Tuple.Create(t.Item1, t.Item2);
    }
}

その後、次のように使用できます

XmlSerializer formatter = new XmlSerializer(
    typeof(List<List<MyTuple<String, CodeExtractor.StatementNode>>>));

formatter.Serialize(fs, results.SelectMany(
                              lst => lst.Select(
                                        t => (MyTuple)t
                                     ).ToList()
                              ).ToList());
于 2012-12-06T08:10:36.737 に答える
1

例外として、次のようになります。シリアライザーにTuple<T1, T2>必要なパラメーターなしのコンストラクターはありません。

于 2012-12-06T08:09:55.620 に答える