これが私の古いクラス図です(簡略化)。
public class Main
Public Property ListOfA As ClassACollection
End Class
Public Class ClassBase
End Class
Public Class ClassA
Inherits ClassBase
End Class
Public Class ClassACollection
Inherits System.Collections.ObjectModel.Collection(Of ClassA)
End Class
Public Class ClassB
Inherits ClassBase
End Class
Public Class ClassBCollection
Inherits System.Collections.ObjectModel.Collection(Of ClassB)
End Class
クラスMain
をシリアル化するとDataContractSerializer
、次のような XML が得られました。
<Main>
<ListOfA>
<ClassA>
.....
</ClassA>
<ClassA>
.....
</ClassA>
</ListOfA>
</Main>
最近、私は削除ClassA
しましClassB
たが、それらは同一でした! 両方のコレクションを削除して、これに置き換えました:
public class Main
Public Property ListOfA As ClassBaseCollection
End Class
Public Class ClassBaseCollection
Inherits System.Collections.ObjectModel.Collection(Of ClassBase)
End Class
しかし、XML をデシリアライズしようとすると、コレクションListOfA
は作成されますが、常に空です。逆シリアル化中にエラーは発生しませんでした。
を使用しようとしましたDataContractResolver
が、関数がorResolveName
を呼び出すことはありません。ClassA
ClassB
Dim dc As New Runtime.Serialization.DataContractSerializer(GetType(Main), Nothing, Integer.MaxValue, False, True, Nothing, New MyResolver())
Private Class MyResolver
Inherits Runtime.Serialization.DataContractResolver
Public Overrides Function ResolveName(typeName As String, typeNamespace As String, declaredType As System.Type, knownTypeResolver As System.Runtime.Serialization.DataContractResolver) As System.Type
If typeName.Equals("ClassA") OrElse typeName.Equals("ClassB") Then
Return GetType(ClassBase)
Else
'Defer to the known type resolver
Return knownTypeResolver.ResolveName(typeName, typeNamespace, Nothing, Nothing)
End If
End Function
End Class
DataContractResolver
私がやりたいことをするのに良い方法ですか?はいの場合、作業を行うために他に何か必要DataContractResolver
ですか?
ご協力いただきありがとうございます!
更新:次のテストを実行するためにプロジェクトに戻っClassA
て
追加しました: - それらを既知のデータ型としてコンストラクター
に配置しようとしました。
- ClassBaseCollection` で試してみました。ClassB
DataContractSerializer
KnownTypeAttribute
この 2 つの状況では、ResolveName
と はまだ呼び出されていませClassA
んClassB
。
から派生したクラスを使用IDataContractSurrogate
して関数の型を変換しようとしましたが、この関数はandGetDataContractType
に対して呼び出されません。ClassA
ClassB
更新 #2: 最後に、やりたいことを行う方法が見つかりませんでした。シリアル化する前に、ファイルのバージョンを確認し、XML 内の古いタグを新しいタグに置き換える必要がありました。元。:
data = data.Replace("<ClassA>", "<ClassBase>")
...
これは私の最初の質問に対する回答ではなく、回避策です。