Search code examples
c#serializationdatacontractserializerdatacontractjsonserializer

How to add save() method generically to classes that have a DataContract?


I have a class with DataContract that can be saved to a file:

using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

namespace Test
{
    [DataContract]
    public class Data
    {
        [DataMember]
        public float Value;

        public static void Main(string[] args)
        {
            Data data = new Data();
            data.Value = 2.3F;

            data.Save(@"D:\result.txt");
        }

        public void Save(string path)
        {
            FileStream stream = new FileStream(path, FileMode.OpenOrCreate);
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Data));

            serializer.WriteObject(stream, this);
        }
    }
}

I have other classes with [DataContract] that I also want to save. I do not want to repeat the code in every class. How can I add the Save() method to all classes that have a [DataContract]?

Ideally, this would work in an extension method with serializer as parameter, but what should the type ??? be?

public static class SaveExtension
{
    public static void Save(this ??? serializable, string path, DataContractSerializer serializer)
    {
        FileStream stream = new FileStream(path, FileMode.OpenOrCreate);

        serializer.WriteObject(stream, serializable);
    }
}

Solution

  • Just make your extension method generic:

        public void Save<T>(this T obj, string path)
        {
            FileStream stream = new FileStream(path, FileMode.OpenOrCreate);
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
    
            serializer.WriteObject(stream, obj);
        }
    

    Then it will work for any type.

    Note that you can create the serializer in the save method since it is passed the type at runtime.