2010-10-27 84 views
0

如果您有一個提供事件的對象並使用克隆該對象的深克隆(序列化)方法,那麼當對象上存在事件時,如何進行該操作連接。附加事件時執行DeepCopy(克隆)

如果我的對象聲明瞭一個事件,但沒有附加任何東西,那麼該對象可以被克隆而沒有問題。

但是,如果對象已附加事件,則序列化失敗。 所有關聯的類都應用了它們的Serializable屬性(除了用於測試的Form1外)。

因此,在下面的示例中,如果我撥打Create(true),克隆將失敗(請參閱最後的例外情況)。

如果我把Create(false)然後它工作正常

的示例代碼是做作,但希望它會表現出什麼,我試圖做的。

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:在程序集'CSharpClonetest,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'中鍵入'CSharpClonetest.Form1'未標記爲可序列化。 處System.Runtime.Serialization.FormatterServices.GetSerializableMembers System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType型) (類型類型,的StreamingContext上下文) 在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上下文,SerObjectInfoInit serObjectInfoInit,IFormatterConverter轉換器,ObjectWriter objectWriter) at System.Ru ntime.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,對象圖) 在CSharpClonetest.Form1.DeepClone [T](T OBJ)在C:\發展\尖峯\ TestDeepCloneEvent \ CSharpClonetest \ Form1.cs中:行30

回答

0

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

+0

所以一旦你這樣做,你如何得到事件反彈,或者你需要做這樣的事情? public rabbit Clone() { Rabbits r; r = DeepClone(this); r.Changed = this.Changed; return r; } – 2010-10-27 04:02:28

+0

@保羅:是的,你這樣做。 – SLaks 2010-10-27 04:28:07

+0

:-(只是希望這個項目是用C#編寫的,我的生活會更容易,因爲VB沒有這個能力(afaik) – 2010-10-27 04:55:10