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

クラスが Serializable としてマークされていることは正しいですが、C# には Seralizable がすべてのフォームに対してシリアライズ可能であることを意味しないという奇妙なことがあります。Serializable 属性は、オブジェクトに対してシリアル化を実行できることのみを示しますが、可能なシリアル化のタイプは示しません。これは、シリアライゼーションを実行できるということではなく、クラスがシリアライゼーションに適格であることを示しています。Xml シリアライゼーションには、オブジェクトに既定のコンストラクターが必要であるという追加の制限があります。XML シリアライゼーションに関する MSDN ドキュメントを参照してください。シリアライゼーションに関する一般的なドキュメントにこの制限が記載されていないことに気付いた場合 ( Serialization Documentation )。

これらの異なるシリアル化が内部でどのように機能するかを考えれば、その理由は明らかです。バイナリ シリアライゼーションを行う場合、型情報がオブジェクトにエンコードされているため、コンストラクターを使用してオブジェクトを作成する必要はありません。Xml Serialzation の場合、フィールドがあるだけなので、できることは新しいオブジェクトを作成して入力することだけです。 これに関する議論については、この投稿を参照してください。この投稿では、これがどのように可能になるか (FormatterServices.GetUninitializedObject() の使用) に関する MSDN の欠点も引用しています。

于 2012-10-02T02:15:28.310 に答える
0

「UsedCulture」のシリアライズ時に、「CultureInfo」を文字列型パラメータに置き換えることをお勧めします。次に、メインコード内で「CultureInfo」タイプに変更します。これは、「CultureInfo をシリアル化できません」と言われているトリックです。これがお役に立てば幸いです。クロッシュ

于 2014-04-12T22:52:39.463 に答える
0

ISerializableを実行してインターフェースを実装する必要がありますpublic class ClassA : Iserializable。さらに、メソッドを実装する必要がありますGetObjectData。1 つの方法は、次のように追加することです。

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 に答える