C# 将CultureInfo对象序列化为另一个类的属性
因此,根据CultureInfo类规范,它是[可序列化的]。然而,当我有另一个[Serializable]类(比如ClassA)引用CultureInfo实例时,我尝试用ClassA创建一个XmlSerializer实例,我会得到一个异常。有人知道附近的工作吗?我想既然CultureInfo是[可序列化的],下面的代码应该可以工作 非常感谢 --代码-- --例外情况-- --附加类--(来自下面的答案)C# 将CultureInfo对象序列化为另一个类的属性,c#,c#-4.0,serialization,cultureinfo,C#,C# 4.0,Serialization,Cultureinfo,因此,根据CultureInfo类规范,它是[可序列化的]。然而,当我有另一个[Serializable]类(比如ClassA)引用CultureInfo实例时,我尝试用ClassA创建一个XmlSerializer实例,我会得到一个异常。有人知道附近的工作吗?我想既然CultureInfo是[可序列化的],下面的代码应该可以工作 非常感谢 --代码-- --例外情况-- --附加类--(来自下面的答案) 您需要通过执行公共类ClassA:ISerializable来实现接口ISerializa
您需要通过执行
公共类ClassA:ISerializable
来实现接口ISerializable
。此外,还必须实现方法GetObjectData
。一种方法可能是添加:
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException("info");
info.AddValue("Culture", UsedCulture);
}
内部
ClassA
。另外,请参见。您认为类被标记为可序列化是正确的,但在C#中有一件奇怪的事情,Seralizable并不意味着它可以序列化到所有形式。Serializable属性仅指示可以对对象执行序列化,但不指示可以执行哪种类型的序列化。这表示该类可用于序列化,而不是可以执行任何序列化。Xml序列化还有一个附加限制,即对象上必须有一个默认构造函数。如果您注意到有关序列化的文档通常没有说明此限制()
如果您想一想这些不同的序列化在幕后是如何工作的,那么这样做的原因应该很清楚。如果正在执行二进制序列化,则不需要使用构造函数来创建对象,因为类型信息是在对象中编码的。对于Xml序列化,您只有字段,所以您所能做的就是创建一个新对象并填充它。这篇文章还引用了MSDN关于如何实现这一点(FormatterServices.GetUninitializedObject()的使用)及其缺点。我建议在序列化“UsedCulture”时,尝试用字符串类型参数替换“CultureInfo”。然后在主代码中将其更改为“CultureInfo”类型。这是一个技巧,正如前面提到的“CultureInfo无法序列化” 希望这有帮助。
库罗什谢谢你的回答。我试过了(附在上面),但仍然得到相同的异常。我的理解是,[Serializable]已经足够了,实现ISerializable接口是没有必要的……或者我遗漏了什么?呃
CultureInfo
看起来并不是真正可以序列化的。检查和
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);
}
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
throw new ArgumentNullException("info");
info.AddValue("Culture", UsedCulture);
}