2

因此,根据 CultureInfo 类规范,它是 [Serializable]。但是,当我有另一个具有对 CultureInfo 实例的引用的 [Serializable] 类(例如 ClassA),并且我尝试使用 ClassA 创建一个 XmlSerializer 实例时,我得到了一个异常。有人知道解决方法吗?我会假设因为 CultureInfo 是 [Serializable] 下面应该工作。

非常感谢!

- 代码 -

using System;
using System.Xml.Serialization;
using System.Globalization;

namespace CultureInfoSerializationTest
{
    class Program
    {
        static void Main(string[] args)
        {
            ClassA aClass = new ClassA();
            aClass.UsedCulture = CultureInfo.CurrentCulture;

            try
            {
                XmlSerializer serializer = new XmlSerializer(typeof(ClassA));
            } catch (Exception e) { }
        }
    }

    [Serializable]
    public class ClassA
    {
        public CultureInfo UsedCulture { get; set; }
    }
}

- 例外 -

System.InvalidOperationException was caught
  HResult=-2146233079
  Message=There was an error reflecting type 'CultureInfoSerializationTest.ClassA'.
  Source=System.Xml
  StackTrace:
       at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
       at System.Xml.Serialization.XmlReflectionImporter.ImportElement(TypeModel model, XmlRootAttribute root, String defaultNamespace, RecursionLimiter limiter)
       at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(Type type, XmlRootAttribute root, String defaultNamespace)
       at System.Xml.Serialization.XmlSerializer..ctor(Type type, String defaultNamespace)
       at System.Xml.Serialization.XmlSerializer..ctor(Type type)
       at CultureInfoSerializationTest.Program.Main(String[] args) in c:\users\asbeug\documents\visual studio 2010\Projects\CultureInfoSerializationTest\CultureInfoSerializationTest\Program.cs:line 18
  InnerException: System.InvalidOperationException
       HResult=-2146233079
       Message=Cannot serialize member 'CultureInfoSerializationTest.ClassA.UsedCulture' of type 'System.Globalization.CultureInfo', see inner exception for more details.
       Source=System.Xml
       StackTrace:
            at System.Xml.Serialization.StructModel.CheckSupportedMember(TypeDesc typeDesc, MemberInfo member, Type type)
            at System.Xml.Serialization.StructModel.GetPropertyModel(PropertyInfo propertyInfo)
            at System.Xml.Serialization.StructModel.GetFieldModel(MemberInfo memberInfo)
            at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)
            at System.Xml.Serialization.XmlReflectionImporter.ImportStructLikeMapping(StructModel model, String ns, Boolean openModel, XmlAttributes a, RecursionLimiter limiter)
            at System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping(TypeModel model, String ns, ImportContext context, String dataType, XmlAttributes a, Boolean repeats, Boolean openModel, RecursionLimiter limiter)
       InnerException: System.InvalidOperationException
            HResult=-2146233079
            Message=System.Globalization.CultureInfo cannot be serialized because it does not have a parameterless constructor.
            InnerException: 

--附加类--(来自下面的答案)

[Serializable]
public class ClassA : ISerializable
{
    public ClassA() { }

    public CultureInfo UsedCulture { get; set; }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
        {
            throw new ArgumentNullException("info");
        }

            info.AddValue("Culture", UsedCulture);
    }
}
4

3 回答 3

5

您是正确的,该类被标记为可序列化,但在 C# 中有一件奇怪的事情,其中​​可序列化并不意味着它可序列化到所有形式。Serializable 属性仅表示可以对对象执行序列化,而不表示可以进行何种类型的序列化。这表示该类有资格进行序列化,而不是可以执行任何序列化。Xml 序列化有一个额外的限制,即对象上必须有一个默认构造函数,请参阅关于 XML 序列化的 MSDN 文档。如果您注意到有关序列化的文档通常没有说明此限制(序列化文档)。

如果您考虑这些不同的序列化是如何在幕后工作的,那么原因应该很清楚。如果您正在执行二进制序列化,则不需要使用构造函数来创建对象,因为类型信息已编码在对象中。对于 Xml 序列化,您只需拥有字段,因此您所能做的就是创建一个新对象并填充它。 有关此问题的一些讨论,请参见这篇文章。该帖子还引用了 MSDN 关于这如何可能(使用 FormatterServices.GetUninitializedObject())的缺点。

于 2012-10-02T02:15:28.310 回答
0

您需要通过执行来实现ISerializable接口public class ClassA : Iserializable。此外,您必须实现方法GetObjectData。一种方法可能是添加:

public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        if (info == null)
            throw new ArgumentNullException("info");

        info.AddValue("Culture", UsedCulture);
    }

里面ClassA。另外,请参阅这篇文章

于 2012-10-01T23:08:43.533 回答
0

我建议您在序列化“UsedCulture”时尝试将“CultureInfo”替换为字符串类型参数。然后在您的主代码中将其更改为“CultureInfo”类型。这是一个技巧,因为它被提到“CultureInfo 不能被序列化”希望这会有所帮助。库罗什

于 2014-04-12T22:52:39.463 回答