2009-07-16 14 views
16

Ho una classe che utilizza uno XmlSerializer nei suoi metodi Read/WriteXml. Il serializzatore è attualmente private readonly.Devo rendere statico questo XmlSerializer?

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); 
    } 
    // ... 
} 

Sto pensando di rendere il Serializzatore private static invece, in modo un caso è condivisa tra tutti i Foos. È una buona idea o ci sono problemi?

risposta

30

Sì, è una buona idea. No, non ci sono problemi con esso. In particolare, la sicurezza thread è non un problema - da MSDN documentation for XmlSerializer class:

Thread Safety

questo tipo è thread-safe.

+2

Ah, grande, questo sta per essere la risposta accettata a meno che Somet hing new arriva. :) – mafu

3

Sì. In generale, vorrai farlo per tutte le tue classi di serializzazione. Si può drasticamente accelerare l'applicazione

Il modo più semplice per farlo è:

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

Poi, quando hai bisogno di un serializzatore si può semplicemente chiamare:

MySerializers.MyType 

Si noti inoltre che in base al C# semantica, le classi statiche sono inizializzate al primo utilizzo, non al momento del caricamento. Se vuoi anticipare tutti i costi di caricamento, devi accedere esplicitamente alla classe.

+0

Buona idea, grazie! +1 – mafu

5

Un modo potrebbe essere quello di creare una fabbrica XmlSerializers e fare riferimento a esso in modo statico (o come un riferimento IOC), qualcosa come:

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>(); 
} 
+0

Molto inefficiente. La risposta di PROGrand è molto meglio: il blocco su T1 non bloccherà T2. – Vlad

13

Secondo Neal - ancora più universale e sicuro attraverso Generics e in sola lettura:

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

Usa come:

Helper<My>.Serializer