我应该将XmlSerializer设置为静态吗?

26

我有一个类,它在其Read/WriteXml方法中使用了XmlSerializer。目前这个序列化器是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);
    }
    // ...
}

我正在考虑将序列化程序 private static 化,这样一个实例将在所有 Foo 之间共享。这是一个好主意吗,还是可能会出现问题?

4个回答

41

2
啊,太好了,除非有新的情况出现,否则这将成为被接受的答案。 :) - mafu

16
根据Neal的说法,通过泛型和只读性,可以使其更加通用和安全:
public static class Helper<T>
{
    public static readonly XmlSerializer Serializer = new XmlSerializer(typeof(T));
}

用法:

Helper<My>.Serializer

7

一种方法是创建一个XmlSerializers工厂并静态引用它(或作为IoC引用),如下所示:

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

非常低效。PROGrand的答案要好得多:在T1上锁定不会阻塞T2。 - Vlad
对于99.99%的调用(当序列化器已经存在时),您可以在锁定之前添加if (serializers.ContainsKey(typeof(T))) return serializers[typeof(T)];以避免线程锁定发生。 - Pavel Biryukov

4

是的。一般情况下,您会希望对所有序列化程序类执行此操作。这可以大幅加快应用程序速度。

最简单的方法是:

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

然后当您需要一个序列化程序时,只需调用:
MySerializers.MyType

需要注意的是,根据C#语义,静态类是在第一次使用时初始化,而不是在加载时初始化。如果你想把所有的负载成本都放在最前面,你需要显式地访问该类。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接