序列化问题:对象XYZ未标记为可序列化. [英] Serialization Issue: Object XYZ is not marked as serializable.

查看:163
本文介绍了序列化问题:对象XYZ未标记为可序列化.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我在序列化方面遇到了一些问题(可能是我的理解).我进行了一些搜索,尽管有很多关于此异常的讨论,但似乎都没有我遇到的那种性质.

首先,为了克服ICloneable的缺点,我改为创建了一个静态实用程序函数,如下所示:

Hello all,

I''m having some sort of issue ( probably my understanding ) with serialization. I did some searching, and while there is a lot of discussion on this exception, none seemed to be of the nature I''m experiencing.

First, to get beyond the shortcomings of the ICloneable, I''ve instead created a static utility function as such:

public class Util
{
public static T DeepClone<T>( T objectToClone )
{
	using( MemoryStream stream = new MemoryStream() )
	{
		BinaryFormatter formatter = new BinaryFormatter();
		formatter.Serialize( stream, objectToClone );
		stream.Position = 0;
		return (T)formatter.Deserialize( stream );
	}
}
}


漂亮的面包和黄油的东西,它按预期工作.

我遇到问题的地方是在从TabPage派生的类中调用DeepClone方法时(我们将其称为MyTabPage).从鼠标按钮处理程序中调用它,并简化了它,就像这样.


Pretty bread and butter stuff and it works as expected.

Where I''m having problems is when calling my DeepClone method from within a class I derived from TabPage ( we''ll call it MyTabPage ). It''s called from within a mouse button handler, and simplified it looks like this.

foreach( MyBaseObject member in selectedMembers )
{
    // Add a copy of the member to the super group''s list.
    superGroup.AddMember( Util.DeepClone<MyBaseObject >( member ) );
}



...,其中selectedMembers是带有MyTabOject的字段,并且是List< MyBaseObject的实例,而MyBaseObject类实际上是用[Serializable]属性修饰的.

该代码可以很好地编译,但是在执行时会引发异常,指出MyTabPage未标记为可序列化.这使我感到困惑.为何编译器会关心MyTabPage?



... where selectedMembers is a field withing MyTabOject and is a List<> of MyBaseObject, and the MyBaseObject class is in fact decorated with the [Serializable] attribute.

The code compiles just fine, but when executed it throws an exception stating that MyTabPage is not marked as serializable. This confuses me. Why does the compiler care about MyTabPage ? Shouldn''t it consider only the type being passed to my DeepClone() utility method?

推荐答案

好,我只是想出了我的问题.首先,我要说的是,你们没有错过任何内容……而是,我缺乏发布完整的代码的原因,因为它太简单了.这是SuperGroup()的构造函数中的问题:

OK, I just figured out my problem. First I''ll say, it''s nothing you guys missed ... rather, it was my lack of posting complete code as there was simply too much to keep it simple. Here''s the problem in the constructor of a SuperGroup():

[Serializable]
public sealed class SuperGroupObject : GroupCadObject
{
    CadPage  cadPage;
    
    public SuperGroup( CadPage cadPage )
    {
        this.cadPage = cadPage;
    }
...



由于我不会详细说明的原因,SuperGroup有必要了解其拥有的CadPage……有些信息必须向上爬到拥有的页面.

如您所见,其中隐藏着与CadPage的神秘链接.即使我没有尝试直接序列化SuperGroup(而是仅序列化其BaseCadObjects列表中的成员),但由于SuperGroup最终派生自BaseCadObject,因此连接显然溢出了.

要解决此问题,它需要执行以下操作:



For reasons I won''t go into detail about, it''s necessary for the SuperGroup to be aware of its owning CadPage ... there''s some information that must flow up hill to the owning page.

As you can see, therein lies the mysterious linkage to the CadPage. Even though I wasn''t trying to directly serialize the SuperGroup ( rather, just members in its list of BaseCadObjects ), apparently the connection spills through because SuperGroup is ultimately derived from a BaseCadObject.

To fix the problem, it requires this:

[Serializable]
public sealed class SuperGroupObject : GroupCadObject
{
    [Nonserialize]
    CadPage  cadPage;

    public SuperGroup( CadPage cadPage )
    {
        this.cadPage = cadPage;
    }
...




我谦虚地吃了我的乌鸦.

谢谢您的时间和考虑.




I humbly eat my crow.

Thanks for you time and consideration.


Robert,
这是一个WinForms应用程序.具体来说,我正在编写电路板CAD应用程序.如果我完成了,那就太好了!如果没有的话,那将是一个不错的C#/.NET练习,不会造成任何损失.

BaseCadObject不是控件,也不是从其他任何东西派生的.它是一个抽象类,当然,它包含创建原理图或PCB时可能绘制的所有(抽象和/或虚拟)属性和方法.它被标记为[serializable],它的所有派生形式也是如此:Line,Pad,Label,Group和SuperGroup.组的不同之处在于,它包括一个List<<>. BaseCadObjects ...用于简化图形对象的分组. SuperGroup成为THE主要组或文件",只需对其进行序列化即可将其保存到磁盘.

对于绘图表面,我包括一个空的TabControl,用于填充WinForm客户区.然后,每个文件都是一个从TabPage派生的"CadPage",其中在构造函数中我实例化了一个PicturBox(以提高渲染效率)并附加了必要的绘制和鼠标处理程序.很简单的东西,即使不是很乏味.

在原始问题/示例中,"selectedItems"是CadPage的一个字段,只是引用SuperGroup中其他对象的BaseCadObjects的一个列表(也是CadPage的一个字段),并且当您按住CTRL键并拖动鼠标时,选择了项目时,一个必须复制所有选定的项目...使用Util.DeepCopy()方法使foreach迭代器变浓,以将它们添加到SuperGroup.

因此,再次,您可以看到此复制机制与序列化CadPage(从TabPage派生)完全无关.如图所示,我将Util.DeepCopy()指向BaseCadObjects,这些都被标记为可序列化的.这些对象没什么特别的.没有委托/事件,没有特殊的接口,只有包含一些属性和方法的简单对象.

我就是不明白.这一定是某种运行时上下文问题,其中串行化知道从中调用它的线程/上下文.如果这是其操作限制之一,那么它与我避免使用的IClonable接口一样无用.非常令人沮丧.

谢谢你的帮助.这位新手很感激.
Robert,
This is a WinForms app. Specifically, I''m writing a circuit board CAD application. If I ever finish it, great! If not, no loss as it''s good C#/.NET exercise.

The BaseCadObject is not a control or derived from anything else. It''s an abstract class that, of course, contains all the (abstract and/or virtual) properties and methods of items one might draw when creating schematics or PCBs. It is marked as [serializable] and so are all it''s derivatives: Line, Pad, Label, Group, and SuperGroup. A group is different in that it includes a List<> of BaseCadObjects ... for simplifying the grouping of graphical objects. The SuperGroup becomes THE main group, or "file" which can be saved to disk by simply serializing it.

For the drawing surface, I include one empty TabControl filling the WinForm client area. Each file is then a "CadPage" derived from TabPage, where in the constructor I instantiate a PicturBox ( for rendering efficiency ) and attach the necessary paint and mouse handlers. Pretty simple stuff, if not tedious.

In the original problem/example, "selectedItems" is a field of CadPage and simply a list of BaseCadObjects that reference other objects in the SuperGroup (also a field of CadPage), and when you CTRL+drag the mouse when items are selected, one must copy all selected items ... hense the foreach iterator using the Util.DeepCopy() method to add them to the SuperGroup.

So, again, you can see that this copy mechanism should have nothing at all to do with serializing the CadPage ( derived from TabPage ). As shown, I''m directing the Util.DeepCopy() at BaseCadObjects, which ARE all marked as serializable. Nothing special about these objects. No delegate/events, no special interfaces, just simple objects containing a few properties and methods.

I just don''t get it. This has to be some sort of run-time context issue, where serialization is aware of the thread/context from which it is called. If that''s one of its operations constraints, it''s about as useless as the IClonable interface I avoided. Very frustrating.

Thanks for any help. This novice appreciates it.


这篇关于序列化问题:对象XYZ未标记为可序列化.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆