2012-10-01 50 views
2

因此,根據CultureInfo類的規範,它是[Serializable]。但是,當我有另一個具有對CultureInfo實例的引用的[Serializable]類(比如說ClassA),並且我嘗試使用ClassA創建一個XmlSerializer實例時,我得到一個異常。任何人都知道工作?我會假設自CultureInfo是[Serializable]下面應該工作。將CultureInfo對象序列化爲另一個類的屬性

非常感謝!

- 代碼 -

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

--Exception--

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: 

--Appended分類 - (從下面的答案)

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

回答

5

你是正確的,該類被標記爲可序列化,但在C#中有一個奇怪的事情,其中​​Seralizable並不意味着它是可序列化的所有形式。 Serializable屬性僅表示可以在對象上執行序列化,但不能執行哪種類型的序列化。這表示該類可以序列化,而不是可以執行任何序列化。 Xml序列化還有一個額外的限制,即對象上必須有一個默認構造函數,請參閱MSDN documentation on XML serialization。如果您注意到序列化文檔通常沒有此限制(Serialization Documentation)。

如果您想了解這些不同的序列化如何在引擎蓋下工作,應該清楚這個原因。如果您正在執行二進制序列化,則構造函數不需要用於創建對象,因爲類型信息是在對象中編碼的。對於Xml Serialziation,您只需擁有這些字段,因此您只需創建一個新對象並填充它即可。 See this post for some discussion around this。這篇文章還引用了MSDN有關這是如何可能的(使用FormatterServices.GetUninitializedObject())的缺點。

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

+0

感謝您的回答。我試過了(如上所示),但仍然得到相同的異常。我的理解是[Serializable]已經足夠了,並且實現ISerializable接口是沒有必要的......或者我在那裏丟失了什麼? –

+0

呃......'CultureInfo'看起來並不像它實際上是可序列化的。檢查http://bytes.com/topic/c-sharp/answers/249442-serializing-cultureinfo-problem和http://social.msdn.microsoft.com/forums/en-US/asmxandxml/thread/0768b13c-edc4 -4cba-8c8e-aaeb6056a215 –

0

我建議您在序列化「UsedCulture」時嘗試用字符串類型參數替換「CultureInfo」。然後在您的主要代碼中將其更改爲「CultureInfo」類型。這是一個竅門,因爲它提到「CultureInfo不能被序列化」 希望這會有所幫助。 Kourosh

相關問題