locked
Deserialize doesn't work on custom List property RRS feed

  • Question

  • Hi,

    I am facing a problem that makes me crazy. I just want to deserialize a list<T>. The serialization process runs fine.

    To reproduce it, I have made this "HelloWorld-of-my-bug" :

    A simple class:
        public class Foo 
        { 
            [XmlAttribute] 
            public String name; 
            public Foo() {} 
     
            public Foo(String nameOfThis) 
            { 
                name = nameOfThis; 
            } 
        } 

    And the container class. It contains a List of Foo I want to serialize/deserialize.

    public class Bar 
        { 
            private List<Foo> list = new List<Foo>(); 
     
            public Bar() {} 
     
            public void Add(String n) 
            { 
                list.Add(new Foo(n)); 
            } 
     
            public List<Foo> l 
            { 
                get 
                { 
    //                 List<Foo> lTemp = new List<Foo>(); 
    //                 foreach (Foo f in list) 
    //                 { 
    //                     if (f.name != "2nd") 
    //                         lTemp.Add(f); 
    //                 } 
    //                 return lTemp; 
                    return list; 
                } 
                set { list = value; } 
            } 
        } 


    And finally the main :

            static void Main(string[] args) 
            { 
                Bar b = new Bar(); 
                b.Add("1er"); 
                b.Add("2nd"); 
                b.Add("3eme"); 
     
                XmlSerializer serializer = new XmlSerializer(typeof(Bar)); 
                StreamWriter myWriter = new StreamWriter("testSerialisation.xml"); 
                serializer.Serialize(myWriter, b); 
                myWriter.Close(); 
     
                Bar myObject; 
                XmlSerializer mySerializer = new XmlSerializer(typeof(Bar)); 
                FileStream myFileStream = new FileStream("testSerialisation.xml", FileMode.Open); 
                myObject = (Bar)mySerializer.Deserialize(myFileStream); 
            } 

    If you run that code, it will works nicely, just as expected. The produced .xml contains 3 Foo entries.

    BUT, if you remove the comments and remove the last list of the "get", the serialize still work (you get only 2 entries, as expected too), but the deserialize does not work any more...

    I don't understand why....because, in both cases, the setter is the same.... It seems that the modification of the getter affects the deserialization process! Or I just missunderstand something somewhere...

    Any ideas ???







    Thursday, January 22, 2009 5:18 PM

Answers

  • In class Bar replace public List<Foo> l code with the following:

     

    public List<Foo> l 
            { 
                get 
                { 
                    if (list == null || list.Count == 0) 
                        return list; 
                    List<Foo> lTemp = new List<Foo>(); 
                     
                    foreach (Foo f in list) 
                    { 
                        if (f.name != "2nd"
                            lTemp.Add(f); 
                    } 
                    return lTemp;  
                    //return list; 
                } 
                set { list = value; } 
            } 

    I just added:

    if (list == null || list.Count == 0)
                        return list;

     at the begginning of the getter. That because when deserializing, the deserializer requires a reference to the object that needs to write to. And you was always returns lTemp that ends with the end of the scope of the getter.

     

    Wish to help you.


    Khaled Moawad --- http://kholyos.blogspot.com
    • Marked as answer by rockeye Friday, January 23, 2009 1:28 PM
    Friday, January 23, 2009 11:37 AM

All replies

  • In class Bar replace public List<Foo> l code with the following:

     

    public List<Foo> l 
            { 
                get 
                { 
                    if (list == null || list.Count == 0) 
                        return list; 
                    List<Foo> lTemp = new List<Foo>(); 
                     
                    foreach (Foo f in list) 
                    { 
                        if (f.name != "2nd"
                            lTemp.Add(f); 
                    } 
                    return lTemp;  
                    //return list; 
                } 
                set { list = value; } 
            } 

    I just added:

    if (list == null || list.Count == 0)
                        return list;

     at the begginning of the getter. That because when deserializing, the deserializer requires a reference to the object that needs to write to. And you was always returns lTemp that ends with the end of the scope of the getter.

     

    Wish to help you.


    Khaled Moawad --- http://kholyos.blogspot.com
    • Marked as answer by rockeye Friday, January 23, 2009 1:28 PM
    Friday, January 23, 2009 11:37 AM
  • Thanks Khaled, it worked perfectly!

     I didn't know the getter was used during deserialize. Good explaination!

    Friday, January 23, 2009 1:28 PM