24

I've got a class which uses an XmlSerializer in its Read/WriteXml methods. The Serializer is currently private readonly.

public class Foo : IXmlSerializable
{
    private Bar _bar = new Bar();
    private readonly XmlSerializer serBar = new XmlSerializer (typeof (Bar));

    public void WriteXml (XmlWriter writer)
    {
        serBar.Serialize (writer, Bar);
    }
    // ...
}

I'm considering making the Serializer private static instead, so one instance is shared between all Foos. Is this a good idea, or are there possible issues?

mafu
  • 31,798
  • 42
  • 154
  • 247

4 Answers4

41

Yes, it is a good idea. No, there aren't any issues with it. In particular, thread safety is not an issue - from MSDN documentation for XmlSerializer class:

Thread Safety

This type is thread safe.

Pavel Minaev
  • 99,783
  • 25
  • 219
  • 289
  • 2
    Ah, great, this is going to be the accepted answer unless something new comes up. :) – mafu Jul 16 '09 at 08:04
16

According to Neal - even more universal and safe through Generics and readonly:

public static class Helper<T>
{
    public static readonly XmlSerializer Serializer = new XmlSerializer(typeof(T));
}

Use as:

Helper<My>.Serializer
PROGrand
  • 186
  • 1
  • 2
7

One way would be to create an XmlSerializers factory and reference it statically (or as an IoC reference), something like:

public class XmlSerializerFactory
{
    public XmlSerializer GetSerializerFor<T>()
    {
        lock (this)
        {
            Type typeOfT = typeof(T);
            if (false == serializers.ContainsKey(typeOfT))
            {
                XmlSerializer newSerializer = new XmlSerializer(typeOfT);
                serializers.Add(typeOfT, newSerializer);
            }

            return serializers[typeOfT];
        }
    }

    private Dictionary<Type, XmlSerializer> serializers = new Dictionary<Type, XmlSerializer>();
}
Igor Brejc
  • 18,714
  • 13
  • 76
  • 95
  • Very inefficient. PROGrand answer is much better: locking on T1 will not block T2. – Vlad Sep 25 '16 at 11:41
  • For 99.99% of calls (when serializer already exists), you can add if (serializers.ContainsKey(typeof(T))) return serializers[typeof(T)]; BEFOR lock - so not thread locks occur – Pavel Biryukov Apr 19 '19 at 08:56
4

Yes. In general you'll want to do this for all of your serializer classes. It can dramatically speed up your application

The easiest way to do this is:

public static class MySerializers {
   public static XmlSerializer MyType = new XmlSerializer(typeof(MyType));    
}

Then when you need a serializer you can simply call:

MySerializers.MyType

Also note that according to C# semantics, static classes are initialized on first use, not at load-time. If you want to put all the load cost up front, you'll need to explicitly access the class.

Neal Tibrewala
  • 435
  • 3
  • 8