I'm working in .NET 4.5.2
According to the .NET documentation, the Dictionary(Of TKey, TValue).KeyCollection Class is not marked serializable. In reflections, it's reporting that it is.
The real problem:
I have a custom dictionary which inherits from the generic .NET dictionary and implements custom serialization. Trying to package the information into the SerializationInfo object, it appends the Keys collection. Since it's marked as serializable (our custom serializer works differently than my sample code, but produces the same result), it attempts to append the serialized object to the collection. When the BinaryFormatter attempts to serialize the KeysCollection, it calls the
.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
method on the custom dictionary, not the KeysCollection. It gets stuck in a loop trying to serialize the collection.
Any ideas on why it's reporting that it's serializable or why the binary formatter calls the GetObjectData method on the superclass instead of the referenced object?
Thanks
I went ahead and posted this to connect.microsoft.com, as I feel the behavior is a bug in the framework. http://ift.tt/1EDTYHm
Simple Program To Reproduce Exception
Imports System.IO
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters
Imports System.Runtime.Serialization.Formatters.Binary
Public Module Program
Public Sub Main()
Dim x As New CustomDictionary(Of String, Integer)
x.Add("TestItem1", 1)
Console.WriteLine("Keys Collection Serializable? {0}", x.Keys.GetType.IsSerializable)
Dim b() As Byte = SerializeSettingsToByteArray(x)
End Sub
Public Function SerializeSettingsToByteArray(obj As Object) As Byte()
Try
Console.WriteLine(String.Format("Serializing {0} Object", obj.GetType().Name))
Dim z As New BinaryFormatter()
z.AssemblyFormat = FormatterAssemblyStyle.Full
Dim m As New MemoryStream()
z.Serialize(m, obj)
Dim b() As Byte
ReDim b(CInt(m.Length - 1))
m.Seek(0, SeekOrigin.Begin)
Dim readCount As Integer = m.Read(b, 0, CInt(m.Length))
Return b
Catch ex As Exception
Throw
End Try
End Function
End Module
<Serializable>
Public Class CustomDictionary(Of TKey, TValue)
Inherits Dictionary(Of TKey, TValue)
Implements ISerializable
Public Sub New()
End Sub
Public Overrides Sub GetObjectData(info As SerializationInfo, context As StreamingContext)
'Not serializing everything for brevity.
info.AddValue("Keys", SerializeSettingsToByteArray(Me.Keys))
End Sub
End Class
Aucun commentaire:
Enregistrer un commentaire