2011-01-04 35 views
4

私はこの質問をしばらく前に聞いたが、役に立たない答えは得られなかった。基本的には、無効なキャスト例外のためにオブジェクトを複製する方法を得ることができません。しかし、私は複製方法の外で物事をうまくキャストすることができます。シリアル化を使用しているときのキャスティングエラー

ここで複製方法

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のでした 未処理メッセージ=キャストできません タイプ01のオブジェクト 型「KH.CharacterClasses.Job」

から「KH.CharacterClasses.Freelancerは」今、私は追加している仕事の種類は、(フリーランサー)仕事から継承したクラスであり、これら二つのコードクラスが以下のとおりです

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

私は本当に何が問題なのか分かりません。私が言ったように、鋳造はこの方法の外でうまく動作し、このコードが以前に働いていたことは分かっています。何か案は?

おかげ

+0

シリアル化コードは大丈夫です。私はこの正確なことをどこかでやっていると確信しています。私は見てみましょう。 –

+0

私は派生した型をシリアル化し、逆シリアル化にそれを基本型の型にキャストします。あなたの問題は非常にうまく見える、私はそれを理解していない。申し訳ありませんが私は助けることはできません。 –

+0

例外スタックトレース全体を提供できますか?内部例外もあります。最後に、キャストを 'T 'に別の行に移動して、オブジェクトを検査することができます。 – leppie

答えて

1

私はそれを理解しました。ある時点で、別のプロジェクトで参照する.dllとしてコンパイルしました。 .dllをbinディレクトリから削除するのを忘れていたので、プログラムは新しいバージョンのコードではなく、DLLからクラスをロードしていました。同じ種類のオブジェクトをまっすぐに複製しようとした後に、.dllと.exeから何かを参照していることがわかりました。 .dllを削除すると修正されました。愚かな私。

0

私はあなただけの重複をしたい、代わりにシリアライズのは、なぜちょうどIClonableを実装していませんか?すべてのタイプには、保護されたメソッドMemberwiseCloneが含まれており、作業がかなり容易になります。

+1

さて、オブジェクトを複製するためのメソッドを1つ、各タイプのメソッドを持つ方が簡単だと思います – Megatron

関連する問題