将CultureInfo对象序列化为另一个类的属性

Ann*_*e B 2 c# serialization cultureinfo c#-4.0

因此,根据CultureInfo类规范,它是[Serializable].但是,当我有另一个[Serializable]类(比如ClassA)具有对CultureInfo实例的引用时,我尝试使用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; }
    }
}
Run Code Online (Sandbox Code Playgroud)

- 例外 -

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: 
Run Code Online (Sandbox Code Playgroud)

- 课程 - (来自下面的答案)

[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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Cra*_*nec 5

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

如果您考虑这些不同的序列化如何在幕后工作,原因应该是清楚的.如果要进行二进制序列化,则不需要使用构造函数来创建对象,因为类型信息是在对象中编码的.对于Xml Serialziation,您只需拥有字段,这样您就可以创建一个新对象并填充它. 看到这个帖子了一些解决这个讨论.该帖还引用MSDN关于这是如何可能的(使用FormatterServices.GetUninitializedObject())这个问题的缺点.