How do I use an XmlSerializer to deserialize an object that might be of a base or derived class without knowing the type beforehand?

前端 未结 5 1733
长情又很酷
长情又很酷 2020-12-08 15:21

In C#, how do I use an XmlSerializer to deserialize an object that might be of a base class, or of any of several derived classes without knowing the type befor

5条回答
  •  抹茶落季
    2020-12-08 15:59

    If you're not set upon using the XmlSerializer you can use the DataContractSerializer with the KnownType attribute instead.

    All you need to do is add a KnownType attribute to the parent class for each sub class and the DataContractSerializer will do the rest.

    The DataContractSerializer will add type information when serializing to xml and use that type information when deserializing to create the correct type.

    For example the following code:

    [KnownType( typeof( C2 ) )]
    [KnownType( typeof( C3 ) )]
    public class C1 {public string P1 {get;set;}}
    public class C2 :C1 {public string P2 {get;set;}}
    public class C3 :C1 {public string P3 {get;set;}}
    
    class Program
    {
      static void Main(string[] args)
      {
        var c1 = new C1{ P1="c1"};
        var c2 = new C2{ P1="c1", P2="c2"};
        var c3 = new C3{ P1="c1", P3="c3"};
    
        var s = new DataContractSerializer( typeof( C1 ) );
        Test( c1, s );
        Test( c2, s );
        Test( c3, s );
      }
    
      static void Test( C1 objectToSerialize, DataContractSerializer serializer )
      {
        using ( var stream = new MemoryStream() )
        {
          serializer.WriteObject( stream, objectToSerialize );
          stream.WriteTo( Console.OpenStandardOutput() );
          stream.Position = 0;
          var deserialized = serializer.ReadObject( stream );
          Console.WriteLine( Environment.NewLine + "Deserialized Type: " + deserialized.GetType().FullName );              
        }
      }
    }
    

    Will output :

    
    c1
    
    Deserialized Type: ConsoleApplication1.C1
    
    
    c1c2
    
    Deserialized Type: ConsoleApplication1.C2
    
    
    c1c3
    
    Deserialized Type: ConsoleApplication1.C3
    

    In the output you'll notice the xml for c2 and c3 contained extra type information which allowed the DataContractSerializer.ReadObject to create the correct type.

提交回复
热议问题