为什么反射报告System.Collections.Generic.Dictionary.KeyCollection对象IsSerializable?

时间:2015-08-20 04:02:08

标签: .net dictionary serialization reflection

我在.NET 4.5.2中工作

根据.NET documentation,字典(Of TKey,TValue).KeyCollection类未标记为可序列化。在反思中,它报告说它是。

真正的问题:
我有一个自定义词典,它继承自通用.NET字典并实现自定义序列化。尝试将信息打包到SerializationInfo对象中,它会附加Keys集合。由于它被标记为可序列化(我们的自定义序列化程序的工作方式与我的示例代码不同,但会产生相同的结果),因此它会尝试将序列化对象附加到集合中。当BinaryFormatter尝试序列化KeysCollection时,它会调用

.GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)

自定义词典上的

方法,而不是KeysCollection。它陷入了试图序列化集合的循环中。

为什么报告它是可序列化的,或者为什么二进制格式化程序在超类而不是引用的对象上调用GetObjectData方法的任何想法?

由于

  
    

我继续把它发布到connect.microsoft.com,因为我觉得这个行为是框架中的错误。 https://connect.microsoft.com/VisualStudio/feedback/details/1689454/dictionary-of-tkey-tvalue-keycollection-reflects-as-serializable-but-binaryformatter-calls-superclass-getobjectdata-method

  

重现异常的简单程序

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

0 个答案:

没有答案