2009-07-16 6 views
16

J'ai une classe qui utilise un XmlSerializer dans ses méthodes Read/WriteXml. Le sérialiseur est actuellement private readonly.Devrais-je rendre ce XmlSerializer statique?

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

J'envisage de faire à la place du sérialiseur private static, donc une instance est partagée entre tous les Foos. Est-ce une bonne idée ou existe-t-il des problèmes?

Répondre

30

Oui, c'est une bonne idée. Non, il n'y a aucun problème avec ça. En particulier, la sécurité des threads est pas un problème - de MSDN documentation for XmlSerializer class:

Sécurité des threads

Ce type est thread-safe.

+2

Ah, grand, cela va être la réponse acceptée à moins SOMET Hing nouveau arrive. :) – mafu

3

Oui. En général, vous voudrez le faire pour toutes vos classes de sérialiseurs. Il peut accélérer considérablement votre application

La meilleure façon de le faire est:

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

Ensuite, lorsque vous avez besoin d'un sérialiseur vous pouvez simplement appeler:

MySerializers.MyType 

Notez également que selon C# sémantique, les classes statiques sont initialisées lors de la première utilisation, pas au moment du chargement. Si vous voulez mettre tout le coût de la charge à l'avant, vous devrez accéder explicitement à la classe.

+0

Bonne idée, merci! +1 – mafu

5

Une façon serait de créer une usine de XmlSerializers et référence statiquement (ou comme une référence IoC), quelque chose comme:

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

Très inefficace. PROGrand réponse est bien meilleure: le verrouillage sur T1 ne bloquera pas T2. – Vlad

13

Selon Neal - par Generics et readonly encore plus universel et sûr:

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

utilisation comme:

Helper<My>.Serializer 
Questions connexes