2010-12-22 3 views
0

Ich habe ein kleines Problem mit einer Datenserialisierungsmethode, die ich zum Kopieren von Objekten verwende. Hier ist die Methode:Objektvervielfältigung/Serialisierungsproblem

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

Das Problem ist folgendes: wenn ich diese Methode aufrufen, unter

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

       Jobs.Add(newcopy); 
      } 
     } 

es diese Ausnahme auslöst:

System.InvalidCastException wurde nicht behandelt Message = Unable um das Objekt des Typs 'KH.CharacterClasses.Freelancer' in den Typ 'KH.CharacterClasses.Job' zu schreiben

Jetzt ist die Art des Jobs, den ich hinzufüge, ein In herited Klasse von Job, (Freelancer) und der Code für diese beiden Klassen ist unter

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

Ich bin ein bisschen hier ratlos, weil ich die ObjectDuplicator Methode kennen funktioniert. In der Tat, dieser Code hat früher funktioniert, aber das war auf einem anderen Computer, und ich habe es nicht in einer Weile angeschaut. Ich bin ein wenig ratlos, warum das Casting hier fehlschlägt. Wenn mir jemand helfen könnte, was falsch ist, wäre das großartig. Wenn Sie mehr Details benötigen, sagen Sie einfach, was Sie brauchen. Ich habe diese Frage gestern gestellt, aber keine brauchbare Antwort bekommen.

Dank

+0

Dieser Code funktioniert nur gut für mich. –

+0

wirklich? Welche Version von .Net verwenden Sie? Ziel-CPU? – Megatron

Antwort

0

Try

return (T)formatter.Deserialize(stream); 

mit

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

ersetzen Was Clone<T> Rückkehr tut? Sehen Sie KH.CharacterClasses.Job in einer Liste von Basistypen? Es scheint, als wäre es nicht der Basistyp für Freelancer.

+0

Yep, dass Verfahren ausgedruckt KH.CharacterClasses.Freelancer KH.CharacterClasses.Job KH.CharacterClasses.Ability KH.StatusEffects.StatusEffect System.Object Sie sind auf jeden Fall die gleiche Basisklasse, wie ich nicht haben Problem beim Umwandeln außerhalb der ObjectDuplicator-Methode – Megatron

+0

Ist ObjectDuplicator in einer separaten Assembly? –

+0

nein, dasselbe Projekt – Megatron

0

Ich würde nie eine Return-Anweisung in eine using-Klausel setzen! Tun Sie dies statt:

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

Wenn die Ausnahme noch geworfen wird, dann Typen in der Tat nicht kompatibel sind ...

+0

Gleiche Ausnahme ... aber ich weiß, dass sie kompatibel sind. Ich kann sie außerhalb dieser Serialisierungsmethode gut umsetzen, und die Basisklasse von Freelancer ist Job – Megatron