开发者

Performing a DeepCopy(clone) when Events are Attached

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.

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).

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

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);
    }
}

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 serializationStr开发者_开发问答eam, 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


Add [field: NonSerialized] to the event declaration.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜