1

インターフェイスメンバー変数を含むクラスがあります。このクラスを逆シリアル化するにはどうすればよいですか。

interface ISensor { }

[Serializable]
class Sensor: ISensor { }

[Serializable]
class Root
{
    [XmlElement("Sensor")]
    public List<ISensor> SensorList{ get; set; }
}

私のXMLは次のようになります

  <?xml version="1.0" encoding="us-ascii"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <Sensor >
        <SensorName>Name1</SensorName>
        <SensorValue>0.0</SensorValue>
    </Sensor>
    <Sensor>
        <SensorName>Name2</SensorName>
        <SensorValue>148.00</SensorValue>
    </Sensor>
</Root>
4

1 に答える 1

1

を使用していると仮定するとXmlSerializer、シリアル化と逆シリアル化の両方に必要な2つの変更があります。

  1. 表示される可能性のあるタイプのリスト、つまり、から継承するタイプをシリアライザーに通知しSensorます。
  2. インターフェイスではなくリストのクラスを使用します。つまり、。に置き換えList<ISensor>ますList<Sensor>

残念ながら、XmlSerializerはインターフェイスを希望どおりに処理しません。詳細については、XmlSerializerシリアル化ジェネリックインターフェイスのリストを参照してください。

基本クラスを使用することができない場合は、を実装することで独自のXMLシリアライザーを作成できますIXmlSerializableReadXmlXMLを手動でオーバーライドして解析します。

例えば:

public interface ISensor { }

[Serializable]
public class Sensor : ISensor { }

[Serializable]
public class Root
{
    // Changed List<ISensor> to List<Sensor>. I also changed
    // XmlElement to XmlArray so it would appear around the list.       
    [XmlArray("Sensor")]
    public List<Sensor> SensorList { get; set; }
}

[Serializable]
public class SensorA : Sensor
{
    [XmlElement("A")]
    public string A { get; set; }
}

[Serializable]
public class SensorB : Sensor
{
    [XmlElement("B")]
    public string B { get; set; }
}

class Program
{
    public static void Main(string[] args)
    {
        XmlSerializer xmlSerializer;

        Root root = new Root();
        root.SensorList = new List<Sensor>();
        root.SensorList.Add(new SensorA() {A = "foo"});
        root.SensorList.Add(new SensorB() {B = "bar"});

        // Tell the serializer about derived types
        xmlSerializer = new XmlSerializer(typeof (Root), 
            new Type[]{typeof (SensorA), typeof(SensorB)});
        StringBuilder stringBuilder = new StringBuilder();
        using (StringWriter stringWriter = new StringWriter(stringBuilder))
        {
            xmlSerializer.Serialize(stringWriter, root);
        }

        // Output the serialized XML
        Console.WriteLine(stringBuilder.ToString());

        Root root2;
        using (StringReader stringReader = new StringReader(stringBuilder.ToString()))
        {
            root2 = (Root) xmlSerializer.Deserialize(stringReader);
        }
    }
}

Console.WriteLineステートメントからの出力は次のとおりです。

<?xml version="1.0" encoding="utf-16"?>
<Root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Sensor>
    <Sensor xsi:type="SensorA">
      <A>foo</A>
    </Sensor>
    <Sensor xsi:type="SensorB">
      <B>bar</B>
    </Sensor>
  </Sensor>
</Root>
于 2013-01-01T07:50:39.533 に答える