因此,根据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; }
}
}
- 异常 -
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);
}
}
答案 0 :(得分:5)
你认为类被标记为Serializable是正确的,但在C#中有一个奇怪的地方,Seralizable并不意味着它可以序列化为所有形式。 Serializable属性仅指示可以对对象执行序列化,但不能指示可以进行哪种类型的序列化。这表示该类可以进行序列化,而不是可以执行任何序列化。 Xml序列化还有一个限制,即对象上必须有默认构造函数,请参阅MSDN documentation on XML serialization。如果您注意到序列化的文档一般没有规定此限制(Serialization Documentation)。
如果您考虑这些不同的序列化如何在幕后工作,原因应该是清楚的。如果要进行二进制序列化,则不需要使用构造函数来创建对象,因为类型信息是在对象中编码的。对于Xml Serialziation,您只需拥有字段,这样您就可以创建一个新对象并填充它。 See this post for some discussion around this。该文章还引用了MSDN关于如何实现这一点(使用FormatterServices.GetUninitializedObject())的缺点。
答案 1 :(得分: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
内。另请参阅this article。
答案 2 :(得分:0)
我建议你在序列化“UsedCulture”时尝试用字符串类型参数替换“CultureInfo”。然后在你的主代码中将其更改为“CultureInfo”类型。这是一个技巧,因为有人提到“CultureInfo无法序列化” 希望这可以帮助。 Kourosh