C# 将HybridDictionary序列化为字节[]

C# 将HybridDictionary序列化为字节[],c#,.net,serialization,C#,.net,Serialization,我写了下面的代码 HybridDictionary state = new HybridDictionary(); using (MemoryStream buffer = new MemoryStream()) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(buffer , state);

我写了下面的代码

HybridDictionary state = new HybridDictionary();

using (MemoryStream buffer = new MemoryStream())
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(buffer , state);


                _backup.Push(buffer .ToArray());

            }
但我在格式化程序上出错。序列化(st,state)如下所示:

" 用户代码未处理System.Runtime.Serialization.SerializationException Message=“Type”System.ComponentModel.ReflectPropertyDescriptor“in Assembly”系统,版本=2.0.0.0,区域性=中性,PublicKeyToken=b77a5c561934e089”未标记为可序列化


这是什么意思?

正如错误所说,您的字典中有System.ComponentModel.ReflectPropertyDescriptor,它没有标记为可序列化。

添加

[field:NonSerializedAttribute()]
public event MyEventHandler SomeEvent;

这将从序列化中忽略它们。

您应该避免序列化事件上已注册的事件处理程序(正如您在上一个答案的注释中所述,您的对象确实有事件)。如果其中一个已注册的处理程序不可序列化,则会引发异常

这个想法源于一个新的想法

以下是我是如何实现这一点的:

    /// <summary>
    /// Occurs when a property value changes.
    /// </summary>
    /// <devdoc>Do not serialize this delegate, since we do not want to have
    /// the event listener persisted.</devdoc>
    [NonSerialized]
    private PropertyChangedEventHandler _propertyChanged;

    /// <summary>
    /// Occurs when a property value changes.
    /// </summary>
    /// <remarks>Effectively, this is fired whenever the wrapped MapXtreme theme 
    /// of the AssociatedTheme property gets changed
    /// via the MapXtreme API.</remarks>
    /// <devdoc>The implementation using the public event and the private delegate is
    /// to avoid serializing the (probably non-serializable) listeners to this event.
    /// see http://www.sanity-free.org/113/csharp_binary_serialization_oddities.html
    /// for more information.
    /// </devdoc>
    public event PropertyChangedEventHandler PropertyChanged
    {
        [MethodImpl(MethodImplOptions.Synchronized)]
        add
        {
            _propertyChanged = (PropertyChangedEventHandler)Delegate.Combine(_propertyChanged, value);
        }
        [MethodImpl(MethodImplOptions.Synchronized)]
        remove
        {
            _propertyChanged = (PropertyChangedEventHandler)Delegate.Remove(_propertyChanged, value);
        }
    }
//
///在属性值更改时发生。
/// 
///不要序列化此委托,因为我们不希望
///事件侦听器持续存在。
[非串行化]
私有财产发生变更的房地产商(u财产发生变更);;
/// 
///在属性值更改时发生。
/// 
///实际上,每当包装的MapXtreme主题
///已更改AssociatedTheme属性的
///通过MapXtreme API。
///使用公共事件和私有委托的实现是
///避免序列化此事件的(可能是不可序列化的)侦听器。
///看http://www.sanity-free.org/113/csharp_binary_serialization_oddities.html
///了解更多信息。
/// 
公共事件属性ChangedEventHandler属性已更改
{
[MethodImpl(MethodImplOptions.Synchronized)]
添加
{
_propertyChanged=(PropertyChangedEventHandler)委托。合并(\u propertyChanged,value);
}
[MethodImpl(MethodImplOptions.Synchronized)]
去除
{
_propertyChanged=(PropertyChangedEventHandler)委托。删除(\u propertyChanged,value);
}
}

向您致意,Marcel

字典的内容是什么,有哪些键和值?实体名称+字段名称和字段值值类型是否包括PropertyDescriptor?听起来可能像BindingList/BindingSource。在从obj获得字段信息后,我得到了BindingSource的当前项并读取了它的字段ect如下代码:“fields=sourceType.GetFields(BindingFlags.NonPublic | BindingFlags.Instance);”我发现两个事件信息进入了“字段”“如何更改上述代码以仅获取值字段而不是事件字段?如果您提到的实体类被放入字典中,则是。”。但是,也看看前面的答案(由米凯尔·斯文森(Mikael Svenson)所作),因为他显然做了与我提议的相同的事情,但方式要简单得多。然而,我没有测试他的解决方案。如果他的解决方案有效,就要表扬他。