6

次のように2つのクラスがあります。

    public class Info
    { 
        [XmlAttribute] public string language;
        public int version;
        public Book book;

        public Info() { }

        public Info(string l, int v, string author, int quantity, int price)
        {
        this.language = l;
        this.version = v;
        book = new Book(author, quantity, price);
        }


    }

    public class Book
    {
            [XmlAttribute] public string author;
            public int quantity;
            public int price;
            [XmlIgnore]public int total;
            public NameValueCollection nvcollection = new NameValueCollection();

            public Book() { }

            public Book(string author, int quantity, int price)
            {
            this.author = author;
            this.quantity = quantity;
            this.price = price;
            total = quantity * price;
            nvcollection.Add(author, price.ToString());
            }

    }

次のように、Info クラスの 2 つのインスタンスを追加する ArrayList を作成しました。

            FileStream fs = new FileStream("SerializedInfo.XML", FileMode.Create);

            List<Info> arrList = new List<Info>();

            XmlSerializer xs = new XmlSerializer(typeof(List<Info>));

            Info pObj = new Info("ABC", 3, "DEF", 2, 6);

            Info pObj1 = new Info("GHI", 4, "JKL", 2, 8);

            arrList.Add(pObj);
            arrList.Add(pObj1);

            xs.Serialize(fs, arrList);

            fs.Close(); 

しかし、シリアル化しようとすると、「型 'System.Collections.Generic.List`1[ConsoleApplicationSerialization.Info]' を反映するエラーが発生しました」という例外が発生します。

どうすればこれをデバッグできますか?

また、namevaluecollection の代わりに、どのタイプの構造体を使用できますか?

4

4 に答える 4

3

NameValueCollectionはICollectionインターフェイスを直接実装しません。代わりに、NameValueCollectionNameObjectCollectionBaseを拡張します。これはICollectionインターフェイスを実装し、オーバーロードされたAdd(system.string) メソッドは NameValueCollectionクラスに実装されていません。XMLSerializerを使用すると、 XmlSerializerはNameValueCollectionをジェネリックICollectionとしてシリアル化または逆シリアル化しようとします。したがって、デフォルトの Add(System.String) を探します。不在の場合Add(system.String)メソッドを使用すると、例外がスローされます。

カスタムのシリアル化でコンテナー クラスを使用してみてください。

http://nayyeri.net/serialize-namevaluecollection

ただし、実際に何を達成しようとしているのかはわかりません。nvcollection には、本の著者と価格以外に何が含まれますか?

ブック レベルで使用する予定ですか、それともオブジェクト階層の上位で使用しますか?

NameValueCollection を使用する代わりに、格納できる内容に関して柔軟性が高いため、Dictionary を使用することをお勧めします

于 2009-09-23T11:41:05.667 に答える
1

内部例外を見てください。

まず、Book クラスをシリアライズ可能にする必要があります。2 つ目は、次の理由により、NameValueCollection を XmlSerializer でシリアル化できないことです。

「XML シリアライズ可能にするには、ICollection から継承する型は、継承階層のすべてのレベルで Add(System.String) を実装する必要があります。System.Collections.Specialized.NameValueCollection は Add(System.String) を実装しません。」

内部例外からのメッセージです。

次のコードで問題なく動作します。

  [Serializable]
        public class Book
        {
            [XmlAttribute]
            public string author;
            public int quantity;
            public int price;
            [XmlIgnore]
            public int total;
            //public NameValueCollection nvcollection = new NameValueCollection();
            public Book() { }
            public Book(string author, int quantity, int price)
            {
                this.author = author;
                this.quantity = quantity;
                this.price = price;
                total = quantity * price;
                //nvcollection.Add(author, price.ToString());
            }
        }
于 2009-09-23T10:23:01.383 に答える
0

私はあなたのコードを実行しました、そしてあなたが得る最も内側の例外はこれです:

XML シリアル化可能にするには、ICollection から継承する型に、継承階層のすべてのレベルで Add(System.String) の実装が必要です。System.Collections.Specialized.NameValueCollection は Add(System.String) を実装していません。

したがって、XML シリアライザーには、より単純な種類のコレクションが必要です。NameValueCollectionシリアル化する前に、名前と値を含むカスタム クラスのリストに変換するのが最善の方法だと思います。

于 2009-09-23T09:59:29.520 に答える
0

更新: NamedValueCollection はシリアル化できないため、実際の問題のようです。おそらく、シリアライズ可能なディクショナリを使用できます。

于 2009-09-23T10:00:46.040 に答える