// There are essentially two kinds of serialization that a program can use: binary  serialization and text serialization.
        // Binary serialization imposes its own format on the data that is being serialized, mapping
        // the data onto a stream of 8-bit values.The data in a stream created by a binaryserializer can only be read by a corresponding binary de-serializer.Binary
        // serialization can provide a complete “snapshot” of the source data. Both publicand private data in an object will be serialized, and the type of each data item is preserved
        public void BinarySerialization()
        {
            MusicDataStore data = MusicDataStore.TestData();

            BinaryFormatter formatter = new BinaryFormatter();

            using (FileStream outputStream =
                       new FileStream("MusicTracks.bin", FileMode.OpenOrCreate, FileAccess.Write))
            {
                formatter.Serialize(outputStream, data);
            }

            MusicDataStore inputData;

            using (FileStream inputStream =
                       new FileStream("MusicTracks.bin", FileMode.Open, FileAccess.Read))
            {
                inputData = (MusicDataStore)formatter.Deserialize(inputStream);
            }

            foreach (var item in inputData.Artists)
            {
                Console.WriteLine(item.Name);
            }

            // Binary serialization is the only serialization technique that serializes private data members by default(i.e.without the developer asking). A file created by a
            // binary serializer can contain private data members from the object being serialized.Note, however, that once an object has serialized there is nothing to
            // stop a devious programmer from working with serialized data, perhaps viewing and tampering with the values inside it.This means that a program should treat
            // deserialized inputs with suspicion.Furthermore, any security sensitive information in a class should be explicitly marked NonSerialized.One way
            // to improve security of a binary serialized file is to encrypt the stream before it is stored, and decrypt it before deserialization.
        }
        // The data contract serializer is provided as part of the Windows Communication Framework(WCF). It is located in the System.Runtime.Serialization
        // library.Note that this library is not included in a project by default. It can be used to serialize objects to XML files. It differs from the XML serializer in the
        // following ways: Data to be serialized is selected using an “opt in” mechanism, so only items
        // marked with the[DataMember] attribute will be serialized. It is possible to serialize private class elements (although of course they will
        // be public in the XML text produced by the serializer).The XML serializer provides options that allow programmers to specify the
        // order in which items are serialized into the data file.These options are notpresent in the DataContract serializer.
        // Once the fields to be serialized have been specified they can be serialized using a DataContractSerializer.
        public void DataContractSerializer()
        {
            MusicDataStore musicData = MusicDataStore.TestData();

            DataContractSerializer formatter = new DataContractSerializer(typeof(MusicDataStore));

            using (FileStream outputStream =
                       new FileStream("MusicTracks.xml", FileMode.OpenOrCreate, FileAccess.Write))
            {
                formatter.WriteObject(outputStream, musicData);
            }

            MusicDataStore inputData;

            using (FileStream inputStream =
                       new FileStream("MusicTracks.xml", FileMode.Open, FileAccess.Read))
            {
                inputData = (MusicDataStore)formatter.ReadObject(inputStream);
            }

            foreach (var item in inputData.Artists)
            {
                Console.WriteLine(item.Name);
            }
        }
        public static MusicDataStore TestData()
        {
            MusicDataStore result = new MusicDataStore();

            result.Artists = new List <ArtistSerializable>
            {
                new ArtistSerializable()
                {
                    Name = "Art1"
                },
                new ArtistSerializable()
                {
                    Name = "Art2"
                },
                new ArtistSerializable()
                {
                    Name = "Art3"
                },
                new ArtistSerializable()
                {
                    Name = "Art4"
                },
                new ArtistSerializable()
                {
                    Name = "Art5"
                }
            };
            result.MusicTracks = new List <MusicTrackSerializable>
            {
                new MusicTrackSerializable()
                {
                    Artist = result.Artists[0], Title = "Title1", Length = 100
                },
                new MusicTrackSerializable()
                {
                    Artist = result.Artists[0], Title = "Title2", Length = 200
                },
                new MusicTrackSerializable()
                {
                    Artist = result.Artists[1], Title = "Title3", Length = 100
                },
                new MusicTrackSerializable()
                {
                    Artist = result.Artists[1], Title = "Title4", Length = 300
                },
                new MusicTrackSerializable()
                {
                    Artist = result.Artists[1], Title = "Title5", Length = 200
                },
            };
            // create the same test data set as	used for the LINQ examples
            return(result);
        }