0

In the following C# serialization & deserialization example, I don't get how "member3" is printed correctly to the console despite not being serialized in the xml file. Same when setting the fields private and therefore they are also not serialized in the data.xml (but still printed to console).

What am I missing?

public class Test
    {
        public static void Main()
        {
            SerializableTestObject testObject = new SerializableTestObject();

            Stream stream = File.Open("data.xml", FileMode.Create);

            XmlSerializer xmlSerializer = new XmlSerializer(typeof(SerializableTestObject));
            xmlSerializer.Serialize(stream, testObject);

            stream.Close();

            testObject = null;

            stream = File.Open("data.xml", FileMode.Open);
            testObject = xmlSerializer.Deserialize(stream) as SerializableTestObject;

            stream.Close();
            testObject?.Print();
        }
    }

    [Serializable]
    public class SerializableTestObject
    {
        public int member1;
        public string member2;
        [NonSerialized] 
            bool member3;

        public SerializableTestObject()
        {
            member1 = 24;
            member2 = "Hello World";
            member3 = true;
        }

        public void Print()
        {
            Console.WriteLine($"member1: {member1}");
            Console.WriteLine($"member2: {member2}");
            Console.WriteLine($"member3: {member3}");
            Console.Read();
        }
    }

`

The console output shows:

member1: 24

member2: Hello World

member3: True

How is member3 set correctly to 'true' despite not being serialized and therefore not deserialized?

I looked through the XmlSerializer documentation but couldn't find what I needed.

Nina
  • 1
  • 1
  • _What am I missing?_: Looks like you're missing an XML file - at least your post is. _"member3" is printed correctly to the console despite not being serialized in the xml file_: We don't know what "correctly" means. Again, where's the XML data? What output did you receive? – Tu deschizi eu inchid Nov 15 '22 at 21:37
  • The console output is as described in the Print method. However, as member3 field is not written into the XML file, it shouldn't be deserializing any content of it and show default/null, should it? – Nina Nov 15 '22 at 21:41
  • I added the console output to the question, as well as a little more details. – Nina Nov 15 '22 at 21:47
  • 1
    Yes, but still no sample XML file. _How is member3 set correctly to 'true'_: You set it to true in the constructor: `member3 = true;`. Instead of placing this code in the constructor, you could have done the following instead: `bool member3 = true;` Use [Properties](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties) instead of "public fields". `public int member1 { get; set; } = 24;` – Tu deschizi eu inchid Nov 15 '22 at 21:50
  • The following may be helpful: [Constructors (C# programming guide)](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/constructors) – Tu deschizi eu inchid Nov 15 '22 at 21:57
  • 1
    Only PUBLIC variables get serialized. Not all your properties are public. – jdweng Nov 16 '22 at 09:46
  • Yes, I know all of that. And the xml is mostly empty. So how is it possible, that an object deserialized from an almost empty xml contains the values that are NOT serialized into the xml? – Nina Nov 16 '22 at 21:17
  • It seems you miss my question and half the code. How can I make my question more easy to understand for you? – Nina Nov 16 '22 at 21:18
  • You've specified `as SerializableTestObject`. When the XML file is deserialized, the default (empty) constructor for the class (`SerializableTestObject`) is called. Since you've specified values in the default constructor these values are populated. There's nothing special about what XML does when creating an instance of the class - it's the normal behavior for class instantiation. – Tu deschizi eu inchid Nov 16 '22 at 22:07
  • There are many ways to read data from an XML file and write data to an XML file. The nice thing about using `XmlSerializer` is that it removes some of the complexity of XML by allowing one to work with classes - which are fundamental to C#. `Default` isn't necessarily `null`. See [Default values of C# types (C# reference)](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/default-values) for more information. The following may also be helpful: https://stackoverflow.com/a/73640395/10024425. – Tu deschizi eu inchid Nov 16 '22 at 22:33
  • This one may be helpful as well: [XmlSerializer Class](https://learn.microsoft.com/en-us/dotnet/api/system.xml.serialization.xmlserializer?view=net-6.0) – Tu deschizi eu inchid Nov 17 '22 at 04:26
  • Incidentally, `[Serializable]` and `[NonSerialized]` control the behavior of the obsolete `BinaryFormatter` and do not affect `XmlSerializer` at all. To prevent a public member from being serialized by `XmlSerializer`, apply `[XmlIgnore]`. See [Control XML serialization using attributes](https://learn.microsoft.com/en-us/dotnet/standard/serialization/controlling-xml-serialization-using-attributes) and [Attributes That Control XML Serialization](https://learn.microsoft.com/en-us/dotnet/standard/serialization/attributes-that-control-xml-serialization). – dbc Nov 23 '22 at 15:26

0 Answers0