を含むオブジェクトをシリアライズ/デシリアライズしようとしていますDictionary<Tuid,Section>
。これらは両方ともカスタム タイプです。
私のコードには、Dictionary<Tuid,Section>
. シリアル化/逆シリアル化しようとしているのはTemplateクラスです。
このコレクションがディクショナリであるという問題を解決するためISerializable
に、テンプレート クラスにインターフェイスを実装しました。
[Serializable]
public class Template : ISerializable
{
protected Template(SerializationInfo info, StreamingContext context)
{
// Deserialize the sections
List<Tuid> tuids = (List<Tuid>)info.GetValue("Sections_Keys", typeof(List<Tuid>));
List<Section> sections = (List<Section>)info.GetValue("Sections_Values", typeof(List<Section>));
this._sections = new Dictionary<Tuid, Section>();
for (int i = 0; i < tuids.Count; i++)
{
_sections.Add(tuids[i], sections[i]);
}
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
List<Tuid> tuids = new List<Tuid>();
List<Section> sections = new List<Section>();
foreach (KeyValuePair<Tuid, Section> kvp in _sections)
{
tuids.Add(kvp.Key);
sections.Add(kvp.Value);
}
info.AddValue("Sections_Keys", tuids, typeof(List<Tuid>));
info.AddValue("Sections_Values", sections, typeof(List<Section>));
}
ここでの戦略は、ディクショナリを 2 つの個別のリストに「アンパック」し、シリアル化されたストリームに個別に保存することです。その後、それらは後で再作成されます。
私のセクションクラスも実装してISerializable
います...
[Serializable]
public class Section : BaseObject
{
protected Section(SerializationInfo info, StreamingContext context):base(.....)
{
// Code
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
// code
}
}
問題はGetObjectData()
、テンプレートとセクションの両方でシリアライズが呼び出されたときに、データがシリアライズ可能であり、シリアライズされていると信じさせることです。
逆シリアル化すると、テンプレートの逆シリアル化コンストラクターのみが呼び出されます。Section の逆シリアル化コンストラクターが呼び出されることはありません。この結果、 への呼び出しinfo.GetValue("Section_Values"....)
はList を返しますが、その中に項目が 1 つあり、その項目は null です。
セクションを逆シリアル化するコンストラクターが呼び出されないのはなぜですか? セクション内のデータの一部がシリアル化できない可能性がありますか? もしそうなら、シリアル化できないものを正確に見つける方法は?
更新:私が見つけた 1 つのことは、セクションの BaseObject が でマークされている[Serializable]
が、実装していないことISerializable
です。
さらに、Deserialize コードがどれほどうるさいのか疑問に思っています。基本クラスも構築するコンストラクターをターゲットにしますか?
アップデート..
わかりました、セクションのシリアライゼーションまで問題を突き止めました。コードは次のようになります...
protected Section(SerializationInfo info, StreamingContext context):base(.....)
{
// Code
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
//info.AddValue("CustomObject", ClientInfo, typeof(CustomObject));
//info.AddValue("Description", Description, typeof(string));
}
両方の行をコメントアウトすると、何もシリアル化されず、逆シリアル化コンストラクターが on で呼び出されますSection
。文字列値を追加しても、すべて問題ありません。ただし、はい-ご想像のとおり-をCustomObject
シリアル化ストリームに追加すると、逆シリアル化コンストラクターは呼び出されません。
ご了承ください...
- 私の逆シリアル化コンストラクター
Section
は空のメソッドです-逆シリアル化されたデータで何もしようとしません。 - Section の基本コンストラクターは、新しい有効なオブジェクトを渡すためにスタブ化されており、これが正常に動作することを確認しました。
CustomObject
をシリアル化できないことを示す例外はスローされません。- は
CustomObject
シリアル化可能であり、そのGetObjectData()
メソッドは正常に実行され、逆シリアル化で正常に構築されます。
このシリアライズ可能なオブジェクトを純粋にストリームに追加するだけで、フレームワークがデシリアライザ コンストラクタに失敗するのは奇妙に思えますSection
。
なぜこれが起こっているのでしょうか?