14

Possible Duplicate:
How to serialize an IList<T>?

I wish to serialize an class (let's call it S) that contains a property of the type IList<T> where T is another class which I have defined. I get an exception when I attempted to serialize an instance of class S to XML. This is understandable as the XmlSerializer doesn't know which concrete class to use. Is there a way, hopefully using attributes, to specify which concrete class to instantiate when serializing/deserializing an instance. My implementation of class S creates a instance of the List<T> class. Here is some code to illustrate my example:

using System;
using System.Xml.Serialization;
using System.IO;

[Serializable]
public class T { }

[Serializable]
public class S
{
    public IList<T> ListOfTs { get; set; }

    public S()
    {
        ListOfTs = new List<T>();
    }
}

public class Program
{
    public void Main()
    {
        S s = new S();
        s.ListOfTs.Add(new T());
        s.ListOfTs.Add(new T());
        XmlSerializer serializer = new XmlSerializer(typeof(S));
        serializer.Serialize(new StringWriter(), s);
    }
}

I'm hoping there's an attribute I can place above the ListOfTs definition that says to the serialize, "assume an instance of List<T> when serializing/deserializing".

Community
  • 1
  • 1
Dan Stevens
  • 6,392
  • 10
  • 49
  • 68

3 Answers3

13

Change the

public IList<T> ListOfTs { get; set; }

to

public List<T> ListOfTs { get; set; }

Then it will work.

Azhar Khorasany
  • 2,712
  • 16
  • 20
  • 5
    I would do this, except this would change the interface for the `S` class. While this is unlikely to have practical impact, but from point of principle, I'd like to see if there's a way to solve the problem without changing the type. – Dan Stevens Apr 04 '12 at 14:16
  • The suggested solution, although is the working one, may ruin your public API architecture – bashis Sep 22 '15 at 18:15
3

I think there's 2 ways that are generally approached for this kind of problem.

One would be to use DataContractSerializer, but since you're already using XmlSerializer, you probably don't want to do that.

The "alternative" is to have a property that is used specifically for the purpose of serialization, and to ignore the IList during serialization.

[Serializable]
public class S
{
    IList<T> _listofTs;

    [XmlIgnore]
    public IList<T> ListOfTs { get _listofTs; set _listofTs = value; }

    [XmlElement(Name="Not Exactly the Greatest Solution!")]
    public List<T> ListOfTs { get _listofTs; set _listofTs = value; }

    public S()
    {
        ListOfTs = new List<T>();
    }
}
Jesse
  • 307
  • 1
  • 5
  • Using XmlIgnore attribute on a property will totally ignore it. The questions is to include the interface property in the serialization. – Azhar Khorasany Apr 04 '12 at 15:45
0

You can implement the IXmlSerializable interface and implement the serialization logic manually using Xml readers and writers.

Dmitry S.
  • 8,373
  • 2
  • 39
  • 49