对象复制/序列化问题

时间:2010-12-22 17:54:20

标签: c# serialization

我正在使用数据序列化方法来复制对象时遇到一些问题。这是方法:

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未处理   Message =无法将类型为'KH.CharacterClasses.Freelancer'的对象强制转换为'KH.CharacterClasses.Job'

现在,我添加的作业类型是来自Job的继承类,(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;
        }
    }

我有点难过,因为我知道ObjectDuplicator方法确实有效。事实上,这个代码之前的HAS工作过,但那是在不同的计算机上,我有一段时间没有看过它。我有点难过为什么铸件在这里失败了。如果有人可以帮我解决什么错误那就太棒了。如果您需要更多细节,请说出您的需求。我昨天问过这个问题,但没有得到可行的答案。

由于

3 个答案:

答案 0 :(得分:0)

尝试替换

return (T)formatter.Deserialize(stream);

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

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

答案 1 :(得分: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;

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

答案 2 :(得分:0)

在这里找出解决方案:

Casting Error when using serialization