問題をできるだけシンプルにしようと思います。以下は、それを示すための 2 つのサンプル プログラムです。分析する必要がある場合は、それを Visual Studio にコピーして貼り付けるだけです。
私の英語にコメントして修正してください。あなたが私を理解できることを願っています。
私の目標は: BaseClass と DerivedClass の 2 つのクラスがあります。
必要がある:
- DerivedClass のインスタンスを作成する
- BaseClass 型の変数に割り当てます
- その変数を XML ファイルにシリアライズする
- そのファイルを BaseClass 型の変数に逆シリアル化します
- その変数には、タイプ DerivedClass のオブジェクトが含まれている必要があります
最初のサンプル プログラムは、「組み込み」のシリアル化を使用しており、問題なく動作します。
しかし、(IXmlSerializable インターフェイスを使用して) シリアル化プロセスをより詳細に制御し、同じ効果を達成したいと考えています。
最初の例:
[Serializable]
public class BaseClass
{
public string property1;
public string property2;
public BaseClass()
{
}
}
[Serializable]
public class DerivedClass : BaseClass
{
public string property3;
public DerivedClass()
{
}
}
class Program
{
static void Main(string[] args)
{
XmlSerializer mySer = new XmlSerializer(typeof(BaseClass), new Type [] {typeof(DerivedClass)});
BaseClass exampleBaseClass;
DerivedClass exampleDerivedClass = new DerivedClass();
exampleDerivedClass.property1 = "Foo";
exampleDerivedClass.property2 = "Bar";
exampleDerivedClass.property3 = "Sth";
exampleBaseClass = exampleDerivedClass;
Console.WriteLine(exampleBaseClass.GetType()); // <----- 1
StreamWriter sw = new StreamWriter("test.xml");
mySer.Serialize(sw, exampleBaseClass); // <----- 2
sw.Close();
StreamReader sr = new StreamReader("test.xml");
exampleBaseClass = (BaseClass)mySer.Deserialize(sr);
Console.WriteLine(exampleBaseClass.GetType()); // <----- 3
Console.ReadKey();
}
}
- これにより、「ConsoleApplication1.DerivedClass が出力されます。問題ありません。
- これにより、3 つのプロパティすべてを含むファイルが作成されます。これで問題ありません。
- これにより、「ConsoleApplication1.DerivedClass が出力されます。問題ありません。
2 番目の例:
[Serializable]
public class BaseClass : IXmlSerializable
{
public string property1;
public string property2;
public BaseClass()
{
}
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public virtual void WriteXml(XmlWriter writer)
{
writer.WriteElementString("property1", property1);
writer.WriteElementString("property2", property2);
}
public virtual void ReadXml(XmlReader reader)
{
while (reader.Read())
switch (reader.Name)
{
case "property1":
property1 = reader.Value;
break;
case "property2":
property2 = reader.Value;
break;
}
}
}
[Serializable]
public class DerivedClass : BaseClass, IXmlSerializable
{
public string property3;
public DerivedClass()
{
}
public override void WriteXml(XmlWriter writer)
{
writer.WriteElementString("property1", property1);
writer.WriteElementString("property2", property2);
writer.WriteElementString("property3", property3);
}
public override void ReadXml(XmlReader reader)
{
while (reader.Read())
switch (reader.Name)
{
case "property1":
property1 = reader.Value;
break;
case "property2":
property2 = reader.Value;
break;
case "property3":
property3 = reader.Value;
break;
}
}
}
class Program
{
static void Main(string[] args)
{
XmlSerializer mySer = new XmlSerializer(typeof(BaseClass), new Type [] {typeof(DerivedClass)});
BaseClass exampleBaseClass;
DerivedClass exampleDerivedClass = new DerivedClass();
exampleDerivedClass.property1 = "Foo";
exampleDerivedClass.property2 = "Bar";
exampleDerivedClass.property3 = "Sth";
exampleBaseClass = exampleDerivedClass;
Console.WriteLine(exampleBaseClass.GetType()); // This prints "ConsoleApplication1.DerivedClass - and it's OK.
StreamWriter sw = new StreamWriter("test.xml");
mySer.Serialize(sw, exampleBaseClass); // This creates file, that starts with xsi:type="DerivedClass" and contains all 3 properties - and it's OK.
sw.Close();
StreamReader sr = new StreamReader("test.xml");
exampleBaseClass = (BaseClass)mySer.Deserialize(sr);
Console.WriteLine(exampleBaseClass.GetType()); // This prints "ConsoleApplication1.DerivedClass - and it's OK. Everything works just great.
Console.ReadKey();
}
}
- これにより、「ConsoleApplication1.DerivedClass が出力されます。問題ありません。
- これにより、3 つのプロパティすべてを含むファイルが作成されます。これで問題ありません。
- これにより、「ConsoleApplication1.BaseClass- and IT IS NOT OK 」が出力されます。結果のオブジェクトには、2 つのプロパティのみが含まれます。
主な質問は次のとおり です。その単純なクラスの定義を変更するにはどうすればよいですか?
助けてくれてありがとう。