"Matryoshka" Class - 读取和写入 XML
"Matryoshka" Class - Reading and Writing to XML
因此,我最近有机会使用一种技术,由于没有更好的术语,我将其命名为 "Matroyshka Class",以俄罗斯嵌套娃娃命名。 class 有一个列表 属性,其中包含相同 class 的实例,每个实例也有一个相似的列表,或多或少是任意的 "depth"。
这是一个简化的示例:
class Doll
{
public string Color;
public List<Doll> ChildDolls;
// End of properties. Getters and Setters not included for readability.
public Doll(string color)
{
this.Color = color;
this.ChildDolls = new List<Doll>();
} // End of Constructor
public void AddChild(Doll NewChild)
{
this.ChildDolls.Add(NewChild);
} // End of Add Child method
public override string ToString()
{
string output;
// Adds the current doll's color
output += this.Color + "\n";
// Adds each doll's children, and each of theirs, and so on...
foreach (Doll Child in this.ChildDolls)
{
output += Child.ToString();
}
return output;
} // End of To String method
} // End of class
总之。我已经运行 有点撞墙了。我需要能够读取它们并将它们写入 XML 文件(或者我想是一些类似的外部文件),因为我的程序最终将涉及其中的 lot;将它们放在代码本身中似乎是不明智的。使用类似于示例的 ToString() 方法的技术,编写应该相对简单。但是,由于 "depth".
的任意性,我缺乏事后阅读它们的想法
System.Xml.Serialization
命名空间中有您需要的一切。以下是您的俄罗斯套娃 class 的外观示例(只需进行一些小改动):
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.Serialization;
public class Doll //must be public
{
public string Color { get; set; }
public List<Doll> ChildDolls { get; set; } = new List<Doll>();
public Doll() //needs a ctor without parameters
{
Color = "Not set";
}
public Doll(string color)
{
this.Color = color;
} // End of Constructor
public void AddChild(Doll NewChild)
{
this.ChildDolls.Add(NewChild);
} // End of Add Child method
public override string ToString()
{
var output = new StringBuilder();
// Adds the current doll's color
output.AppendLine(Color);
// Adds each doll's children, and each of theirs, and so on...
foreach (Doll Child in this.ChildDolls)
{
output.Append(Child.ToString());
}
return output.ToString();
} // End of To String method
} // End of class
这里是 serialization/deserialization 方法:
public static void Serialize(string path, Doll matryoshka)
{
using (var writer = new StreamWriter(path))
{
var s = new XmlSerializer(typeof(Doll));
s.Serialize(writer, matryoshka);
}
}
public static Doll Deserialize(string path)
{
using (var reader = new StreamReader(path))
{
var x = new XmlSerializer(typeof(Doll));
return (Doll)x.Deserialize(reader);
}
}
使用它们非常简单:
var redDoll = new Doll("red");
var green1Doll = new Doll("green1");
var green2Doll = new Doll("green2");
var blue1Doll = new Doll("blue1");
var blue2Doll = new Doll("blue2");
redDoll.AddChild(green1Doll);
redDoll.AddChild(green2Doll);
green1Doll.AddChild(blue1Doll);
green2Doll.AddChild(blue2Doll);
Serialize("dolls.xml", redDoll);
结果会是这样的:
<?xml version="1.0" encoding="utf-8"?>
<Doll xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Color>red</Color>
<ChildDolls>
<Doll>
<Color>green1</Color>
<ChildDolls>
<Doll>
<Color>blue1</Color>
<ChildDolls />
</Doll>
</ChildDolls>
</Doll>
<Doll>
<Color>green2</Color>
<ChildDolls>
<Doll>
<Color>blue2</Color>
<ChildDolls />
</Doll>
</ChildDolls>
</Doll>
</ChildDolls>
</Doll>
反序列化也能正常工作:
var deserializedDoll = Deserialize("dolls.xml");
Console.Write(deserializedDoll.ToString());
正如预期的那样,输出是:
red
green1
blue1
green2
blue2
您还可以使用属性控制序列化程序如何生成您的 XML。这是 docs
因此,我最近有机会使用一种技术,由于没有更好的术语,我将其命名为 "Matroyshka Class",以俄罗斯嵌套娃娃命名。 class 有一个列表 属性,其中包含相同 class 的实例,每个实例也有一个相似的列表,或多或少是任意的 "depth"。
这是一个简化的示例:
class Doll
{
public string Color;
public List<Doll> ChildDolls;
// End of properties. Getters and Setters not included for readability.
public Doll(string color)
{
this.Color = color;
this.ChildDolls = new List<Doll>();
} // End of Constructor
public void AddChild(Doll NewChild)
{
this.ChildDolls.Add(NewChild);
} // End of Add Child method
public override string ToString()
{
string output;
// Adds the current doll's color
output += this.Color + "\n";
// Adds each doll's children, and each of theirs, and so on...
foreach (Doll Child in this.ChildDolls)
{
output += Child.ToString();
}
return output;
} // End of To String method
} // End of class
总之。我已经运行 有点撞墙了。我需要能够读取它们并将它们写入 XML 文件(或者我想是一些类似的外部文件),因为我的程序最终将涉及其中的 lot;将它们放在代码本身中似乎是不明智的。使用类似于示例的 ToString() 方法的技术,编写应该相对简单。但是,由于 "depth".
的任意性,我缺乏事后阅读它们的想法System.Xml.Serialization
命名空间中有您需要的一切。以下是您的俄罗斯套娃 class 的外观示例(只需进行一些小改动):
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml.Serialization;
public class Doll //must be public
{
public string Color { get; set; }
public List<Doll> ChildDolls { get; set; } = new List<Doll>();
public Doll() //needs a ctor without parameters
{
Color = "Not set";
}
public Doll(string color)
{
this.Color = color;
} // End of Constructor
public void AddChild(Doll NewChild)
{
this.ChildDolls.Add(NewChild);
} // End of Add Child method
public override string ToString()
{
var output = new StringBuilder();
// Adds the current doll's color
output.AppendLine(Color);
// Adds each doll's children, and each of theirs, and so on...
foreach (Doll Child in this.ChildDolls)
{
output.Append(Child.ToString());
}
return output.ToString();
} // End of To String method
} // End of class
这里是 serialization/deserialization 方法:
public static void Serialize(string path, Doll matryoshka)
{
using (var writer = new StreamWriter(path))
{
var s = new XmlSerializer(typeof(Doll));
s.Serialize(writer, matryoshka);
}
}
public static Doll Deserialize(string path)
{
using (var reader = new StreamReader(path))
{
var x = new XmlSerializer(typeof(Doll));
return (Doll)x.Deserialize(reader);
}
}
使用它们非常简单:
var redDoll = new Doll("red");
var green1Doll = new Doll("green1");
var green2Doll = new Doll("green2");
var blue1Doll = new Doll("blue1");
var blue2Doll = new Doll("blue2");
redDoll.AddChild(green1Doll);
redDoll.AddChild(green2Doll);
green1Doll.AddChild(blue1Doll);
green2Doll.AddChild(blue2Doll);
Serialize("dolls.xml", redDoll);
结果会是这样的:
<?xml version="1.0" encoding="utf-8"?>
<Doll xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Color>red</Color>
<ChildDolls>
<Doll>
<Color>green1</Color>
<ChildDolls>
<Doll>
<Color>blue1</Color>
<ChildDolls />
</Doll>
</ChildDolls>
</Doll>
<Doll>
<Color>green2</Color>
<ChildDolls>
<Doll>
<Color>blue2</Color>
<ChildDolls />
</Doll>
</ChildDolls>
</Doll>
</ChildDolls>
</Doll>
反序列化也能正常工作:
var deserializedDoll = Deserialize("dolls.xml");
Console.Write(deserializedDoll.ToString());
正如预期的那样,输出是:
red
green1
blue1
green2
blue2
您还可以使用属性控制序列化程序如何生成您的 XML。这是 docs