本文介绍了在连接事件时执行DeepCopy(克隆)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当您有一个提供事件的对象,并且使用deepclone(序列化)方法来克隆对象时,如果实际附加对象上的事件,那么该怎么做。

When you have an object that provides events and you use a deepclone (serialisation) approach to cloning the object, how do you do it when there are events on the object that are actually attached.

如果我的对象声明一个事件,但没有附加任何东西,那么对象可以被克隆而不会发生问题。

If my object declares an event, but nothing is attached then object can be cloned without issue.

但是如果对象已经附加了事件,那么序列化失败。
所有关联的类都应用了它们的Serializable属性(除了用于测试的Form1)。

BUT if the object has had events attached, then the serialisation fails.All the associated classes have their Serializable attribute applied (except the Form1, which is being used for testing).

所以在下面的例子中,如果我打电话创建(true)然后克隆失败(请参阅结束时的异常)。

So in the following example, if i call Create(true) then the Clone fails (see exception at the end).

如果我调用创建(false)然后它正常工作

If I call Create(false) then it works properly

示例代码被设计,但希望它将演示我正在尝试

The example code is contrived, but hopefully it will demonstrate what I'm trying to do.

private void Create(bool useEvent)
{
    mRab = new Rabbits();

    if (useEvent) mRab.Changed += new Rabbits.ChangedEventHandler(ChangedRabbits);

    Rabbit  r;
    r = new Rabbit();
    r.Monkeys.Add(new Monkey("Test"));
    mRab.Add(r);

    Rabbits r2;
    r2 = DeepClone(mRab);
}

public static T DeepClone<T>(T obj)
{
    using (var ms = new MemoryStream())
    {
        var f = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
        f.Serialize(ms, obj);
        ms.Position = 0;
        return (T)f.Deserialize(ms);
    }
}

克隆事件附加时的异常。
System.Runtime.Serialization.SerializationException:在Assembly'CSharpClonetest,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'中键入'CSharpClonetest.Form1'未标记为可序列化。
在System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType类型)
在System.Runtime.Serialization.FormatterServices.GetSerializableMembers(类型类型,StreamingContext上下文)
在System.Runtime.Serialization。 Formatters.Binary.WriteObjectInfo.InitMemberInfo()
在System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj,ISurrogateSelector代理选择器,StreamingContext上下文,SerObjectInfoInit serObjectInfoInit,IFormatterConverter转换器,ObjectWriter objectWriter)
在System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj,ISurrogateSelector surrogateSelector,StreamingContext context,SerObjectInfoInit serObjectInfoInit,IFormatterConverter转换器,ObjectWriter objectWriter)
在System.Runtime.Serialization.Formatters.Binary.ObjectWriter。写(WriteObjectInfo objectInfo,NameInfo memberNameInfo,NameInfo typeNameInfo)
在System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph,Header [] inHeaders,__BinaryWriter serWriter,Boolean fCheck)
在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream,对象图,Header []头,Boolean fCheck)
在System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream,Object graph)
在CSharpClonetest.Form1.DeepClone [T]( T obj)在C:\Development\Spikes\TestDeepCloneEvent\CSharpClonetest\Form1.cs:行30

The exception when Cloning when the event is attached. System.Runtime.Serialization.SerializationException: Type 'CSharpClonetest.Form1' in Assembly 'CSharpClonetest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable. at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo) at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph) at CSharpClonetest.Form1.DeepClone[T](T obj) in C:\Development\Spikes\TestDeepCloneEvent\CSharpClonetest\Form1.cs:line 30

推荐答案

[field:NonSerialized] 添加到事件声明中。

这篇关于在连接事件时执行DeepCopy(克隆)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-10 20:53