2017-03-10 24 views
0

1つのXMLファイルに複数のオブジェクトを保存して読み込もうとしています。オブジェクトリストの削除/シリアル化

シリアライズ機能は既存のリストとは機能しませんが、その理由はわかりません。私はすでにそれをコンパイルしようとしましたが、メソッドにオブジェクトのレフェレンスが必要であるというエラーが表示されます。

のProgram.cs:

class Program 
    { 
     static void Main(string[] args) 
     { 
      List<Cocktail> lstCocktails = new List<Cocktail>(); 
      listCocktails.AddRange(new Cocktail[] 
      { 
       new Cocktail(1,"Test",true,true, 
       new Cocktail(1, "Test4", true, true, 0) 
     }); 


      Serialize(lstCocktails); 

     } 

     public void Serialize(List<Cocktail> list) 
     { 
      XmlSerializer serializer = new XmlSerializer(typeof(List<Cocktail>)); 
      using (TextWriter writer = new StreamWriter(@"C:\Users\user\Desktop\MapSample\bin\Debug\ListCocktail.xml")) 
      { 
       serializer.Serialize(writer, list); 
      } 
     } 

     private void DiserializeFunc() 
     { 
      var myDeserializer = new XmlSerializer(typeof(List<Cocktail>)); 
      using (var myFileStream = new FileStream(@"C:\Users\user\Desktop\MapSample\bin\Debug\ListCocktail.xml", FileMode.Open)) 
      { 
       ListCocktails = (List<Cocktail>)myDeserializer.Deserialize(myFileStream); 
      } 
     } 

Cocktail.cs:

[Serializable()] 
    [XmlRoot("locations")] 
    public class Cocktail 
    { 

     [XmlElement("id")] 
     public int CocktailID { get; set; } 
     [XmlElement("name")] 
     public string CocktailName { get; set; } 
     [XmlElement("alc")] 
     public bool alcohol { get; set; } 
     [XmlElement("visible")] 
     public bool is_visible { get; set; } 
     [XmlElement("counter")] 
     public int counter { get; set; } 
     private XmlSerializer ser; 

     public Cocktail() { 
      ser = new XmlSerializer(this.GetType()); 
     } 
     public Cocktail(int id, string name, bool alc,bool vis,int count) 
     { 
      this.CocktailID = id; 
      this.CocktailName = name; 
      this.alcohol = alc; 
      this.is_visible = vis; 
      this.counter = count; 
     } 
    } 
} 

Iiはまた、私はDiserializeFuncで何かを台無しだと思います()。

+0

シリアル化エラーが発生した場合は、それを投稿すると役に立ちます。また、[try catchの内部エラー](https://stackoverflow.com/questions/22826067/what-is-inner-exception)を分析することで、エラーを試してみることをお勧めします。 [このリストのシリアライズに関するチュートリアル](https://www.dotnetperls.com/serialize-list)に従うこともできます –

+0

問題は何ですか?あなたはポストに言及していません –

+0

サイドノート:「新しいここ」、「ありがとう」、「私はボブ・ザ・サード」(または他の署名)のような問題とは無関係のテキストを避けてください。代わりに、ポストに提供されているコードが[MCVE]のガイドラインと、投稿にある入力/出力/エラーメッセージのようなすべての必要な情報に従っていることを確認してください。 –

答えて

0

あなたはCocktailクラスを正しく実装していますが、リストをシリアライズする方法については混乱していると思います。カクテルオブジェクトクラスの実装は完全にうまくいきます。リスト関連の関数を取り除くだけです。

using System; 
using System.Xml.Serialization; 

namespace Serialization_Help 
{ 
    [Serializable()] 
    [XmlRoot("locations")] 
    public class Cocktail 
    { 

     [XmlElement("id")] 
     public int CocktailID { get; set; } 
     [XmlElement("name")] 
     public string CocktailName { get; set; } 
     [XmlElement("alc")] 
     public bool alcohol { get; set; } 
     [XmlElement("visible")] 
     public bool is_visible { get; set; } 
     [XmlElement("counter")] 
     public int counter { get; set; } 
     public Cocktail() { 

     } 
     public Cocktail(int id, string name, bool alc, bool vis, int count) 
     { 
      this.CocktailID = id; 
      this.CocktailName = name; 
      this.alcohol = alc; 
      this.is_visible = vis; 
      this.counter = count; 
     } 
    } 
} 

新しい機能では、リストを直接シリアル化する必要があります。

using System.Collections.Generic; 
using System.IO; 
using System.Xml.Serialization; 

namespace Serialization_Help 
{ 
    class Program { 
     static void Main(string[] args) { 
      List<Cocktail> list = new List<Cocktail> { 
       new Cocktail(01, "rum and coke", true, true, 5), 
       new Cocktail(02, "water on the rocks", false, true, 3) 
      }; 
      Serialize(list); 
      List<Cocktail> deserialized = DiserializeFunc(); 
     } 

     public static void Serialize(List<Cocktail> list) { 

      XmlSerializer serializer = new XmlSerializer(typeof(List<Cocktail>)); 
      using (TextWriter writer = new StreamWriter(Directory.GetCurrentDirectory() + @"\ListCocktail.xml")) serializer.Serialize(writer, list); 
     } 

     private static List<Cocktail> DiserializeFunc() { 
      var myDeserializer = new XmlSerializer(typeof(List<Cocktail>)); 
      using (var myFileStream = new FileStream(Directory.GetCurrentDirectory() + @"\ListCocktail.xml", FileMode.Open)) return (List<Cocktail>)myDeserializer.Deserialize(myFileStream); 
     } 
    } 
} 

そうすることは正しく、次の.xml出力をプリントアウトする必要があります。

<?xml version="1.0" encoding="utf-8"?> 
<ArrayOfCocktail xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Cocktail> 
    <id>1</id> 
    <name>rum and coke</name> 
    <alc>true</alc> 
    <visible>true</visible> 
    <counter>5</counter> 
    </Cocktail> 
    <Cocktail> 
    <id>2</id> 
    <name>water on the rocks</name> 
    <alc>false</alc> 
    <visible>true</visible> 
    <counter>3</counter> 
    </Cocktail> 
</ArrayOfCocktail> 

は、私は、ファイルのための標準的な安全性またはnullチェックのいずれかの実装を提供していないことに注意してください。 File.Exists(...)(see here for File.Exists implementation)を使用してファイルが存在するかどうかを確認し、正しいtrycatchのケースと、シリアライズまたは入力/出力エラーが発生した場合のコードの選択を実装する必要があります。

+0

偉大な答えをいただきありがとうございました!これは私のプログラムの基礎として私を助けます!その準備ができればあなたはカクテルを手に入れます;):D –

0

ExtendedXmlSerializerを使用してシリアル化して逆シリアル化することをお勧めします。

インスタレーション あなたはnugetからExtendedXmlSerializerをインストールするか、次のコマンドを実行することができます。

Install-Package ExtendedXmlSerializer 

シリアライズ:

ExtendedXmlSerializer serializer = new ExtendedXmlSerializer(); 
var list = new List<Cocktail>(); 
var xml = serializer.Serialize(list); 

デシリアライズ

var list = serializer.Deserialize<List<Cocktail>>(xml); 

.NETの標準XMLシリアライザは非常に限定されています。

  • はあなたの場合はXMLの古いバージョンを読み込むためのメカニズム、
  • はありません
  • 、辞書をサポートしていません
  • 、界面特性を持つ循環参照またはクラスを持つクラスの直列化をサポートしていませんカスタムシリアライザを作成するには、クラスがIXmlSerializableから継承する必要があります。これは、クラスがPOCOクラスではないことを意味します。
  • IoCをサポートしていません。

ExtendedXmlSerializerでこれを行うことができます。

ExtendedXmlSerializerサポート.NET 4.5以上と.NETのコア。 WebApiとAspCoreを統合することができます。

関連する問題