2010-12-22 62 views
0

我遇到了一個用於複製對象的數據序列化方法的問題。這裏的方法:對象複製/序列化問題

public static class ObjectDuplicator 
     { 
      public static T Clone<T>(T source) 
      { 
       if (!typeof(T).IsSerializable) 
       { 
        throw new ArgumentException("the Type must be serializable.", "source"); 
       } 

       if (Object.ReferenceEquals(source, null)) //dont try to serialize a null object 
       { 
        return default(T); 
       } 

       IFormatter formatter = new BinaryFormatter(); 
       Stream stream = new MemoryStream(); 
       using (stream) 
       { 
        formatter.Serialize(stream, source); 
        stream.Seek(0, SeekOrigin.Begin); 
        return (T)formatter.Deserialize(stream); 
       } 
      } 
     } 

問題是這樣的:當我打電話使用的代碼這種方法如下

public void AddJob(Job job) 
     { 
      if (!Jobs.Contains(job)) 
      { 
       Job newcopy = Utilities.ObjectDuplicator.Clone<Job>(job); 

       Jobs.Add(newcopy); 
      } 
     } 

它拋出這個異常:

System.InvalidCastException了未處理 消息=無法投入'KH.CharacterClasses.Freelancer'類型的對象來鍵入'KH.CharacterClasses.Job'

現在,我添加的工作類型是一個in從工作herited類,(自由職業者)和代碼這兩個類低於

[Serializable] 
    public class Job : Ability 
    { 
     protected JobCommand basecommand1; 
     protected JobCommand basecommand2; 
     protected JobCommand basecommand3; 
     protected JobCommand basecommand4; 
     protected JobCommand command1; 
     protected JobCommand command2; 
     protected JobCommand command3; 
     protected JobCommand command4; 
     bool mastered; 
     protected FFJob job; 
     protected string name; 
     int level; 

     public FFJob SetJob 
     { 
      get 
      { 
       return job; 
      } 
     } 
     public bool Mastered 
     { 
      get 
      { 
       return mastered; 
      } 
     } 

     public JobCommand Command1 
     { 
      get 
      { 
       return command1; 
      } 
      set 
      { 
       command1 = value; 
      } 
     } 

     public JobCommand DefaultCommand1 
     { 
      get 
      { 
       return basecommand1; 
      } 
     } 

     public JobCommand Command2 
     { 
      get 
      { 
       return command2; 
      } 
      set 
      { 
       command2 = value; 
      } 
     } 

     public JobCommand DefaultCommand2 
     { 
      get 
      { 
       return basecommand2; 
      } 
     } 

     public JobCommand Command3 
     { 
      get 
      { 
       return command3; 
      } 
      set 
      { 
       command3 = value; 
      } 
     } 

     public JobCommand DefaultCommand3 
     { 
      get 
      { 
       return basecommand3; 
      } 
     } 

     public JobCommand Command4 
     { 
      get 
      { 
       return command4; 
      } 
      set 
      { 
       command4 = value; 
      } 
     } 

     public JobCommand DefaultCommand4 
     { 
      get 
      { 
       return basecommand4; 
      } 
     } 

     public Job(string name, string description, int jobID) 
      : base(name, description, jobID, -1, -1, null, null, -1, -1) 
     { 
     } 

     public static bool operator ==(Job job1, Job job2) 
     { 
      if (System.Object.ReferenceEquals(job1, job2)) 
       return true; 
      if (((object)job1 == null) || ((object)job2 == null)) 
       return false; 
      return (job1.Name == job2.Name && job1.UID == job2.UID); 
     } 

     public static bool operator !=(Job job1, Job job2) 
     { 
      return !(job1 == job2); 
     } 


     // public abstract void CharacterModifier(BaseCharacter character); 

     // public abstract void CharacterDemodifier(BaseCharacter character); 
    } 

    [Serializable] 
    public class Freelancer : Job 
    { 
     public Freelancer() 
      : base("Freelancer", "A character not specializing in any class. Can combine the power of all mastered Jobs.", Globals.JobID.ID) 
     { 
      basecommand1 = JobCommand.Attack; 
      basecommand2 = JobCommand.Free; 
      basecommand3 = JobCommand.Free; 
      basecommand4 = JobCommand.Items; 
      command1 = basecommand1; 
      command2 = basecommand2; 
      command3 = basecommand3; 
      command4 = basecommand4; 
      job = FFJob.Freelancer; 
     } 
    } 

我有點難倒在這裏,因爲我知道ObjectDuplicator方法確實可行。事實上,以前的代碼已經工作過了,但那是在一臺不同的計算機上,而我一段時間沒有看過它。我有點難以理解爲什麼這裏的演員失敗了。如果有人能幫助我解決那些很棒的問題。如果你需要更多的細節,只需說出你需要的。我昨天問了這個問題,但沒有得到一個可行的答案。

感謝

+0

該代碼工作剛剛對於我來說足夠了。 – 2010-12-22 18:09:02

+0

真的嗎?你使用的是什麼樣的.Net?目標CPU? – Megatron 2010-12-22 18:28:20

回答

0

嘗試

var result = formatter.Deserialize(stream); 
for (Type now = result.GetType(); now != null; now = now.BaseType) 
    MessageBox.Show(now.FullName); 
return result as T; 

更換

return (T)formatter.Deserialize(stream); 

什麼Clone<T>回報?您是否在基本類型列表中看到KH.CharacterClasses.Job?似乎它不是Freelancer的基本類型。

+0

是的那種方法打印出來 KH.CharacterClasses.Freelancer KH.CharacterClasses.Job KH.CharacterClasses.Ability KH.StatusEffects.StatusEffect System.Object的 他們是絕對相同的基類,因爲我沒有在ObjectDuplicator方法之外將其轉換爲錯誤 – Megatron 2010-12-22 18:33:32

0

我永遠不會把return語句放入using子句中!做到這一點,而不是:

object tClone = null; 
using (Stream stream = new MemoryStream()) { 
formatter.Serialize(stream, source); 
stream.Seek(0, SeekOrigin.Begin); 
tClone = formatter.Deserialize(stream); 
} 
return (T)tClone; 

如果異常仍拋出,那麼你的類型的實際不兼容...