mercredi 19 août 2015

Why does reflections report that System.Collections.Generic.Dictionary.KeyCollection object IsSerializable?

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