2010-12-22 53 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; 

如果异常仍抛出,那么你的类型的实际不兼容...