我有一个Generic类,它接受类型为T的对象,将其序列化为XML,然后将其保存到文件系统。目前,如果对象不可序列化,则序列化操作将失败。这不是问题,但我认为最好在我的类构造函数中检查T的实例是否可序列化,如果不是,则在该点抛出错误而不是稍后抛出错误。
有没有一种检查T实例的方法可以序列化为XML,而不是简单地实例化它并尝试在TRY ... CATCH中序列化它?如果我能以某种方式查询类T以发现它是否可以序列化为XML,那将是很好的。
如果有帮助,可以在此处查看代码:http://winrtstoragehelper.codeplex.com/SourceControl/changeset/view/ac24e6e923cd#WinRtUtility%2fWinRtUtility%2fObjectStorageHelper.cs
请注意,此代码是针对WinRT编译的(即,它用于Windows 8应用程序)但是我认为这个问题与C#的任何方言都有关。
提前致谢
杰米
答案 0 :(得分:4)
AFAIK,即使您检查各种属性(Serializable
,DataContract
)或检查Type.IsSerializable
(我认为这只是检查{{1}的便捷方法) }属性存在)它不保证实现的实现可序列化。 (编辑:如上所述,并且在问题中提供的示例代码中看到,Serializable
不依赖于XmlSerializer
属性装饰。因此检查这些标志没有任何意义。)< / em>的
根据我的经验,您最好的选择是使用单元测试来验证应用程序中使用的各种类型,并使用try / catch查看它是否通过。在运行时,使用try / catch(而不是每次预先检查)并记录/处理异常。
如果您的单元测试结果列出了有效的兼容类型,则可以根据先前测试确定的编译时列表预先检查Serializable
并假设其他任何类型类型没有好处。可能想要查看已知有效类型的子类,即使它们从有效的可序列化类型继承,它们的实现也可能不是。
T
(事实上,它甚至不存在于Silverlight中)。内置的[Serializable]
适用于所有公共财产,无论装饰如何。查看它是否可序列化的唯一方法是尝试序列化并尝试/捕获失败,或编写算法来检查每个属性(并递归地通过子对象)并检查每个类型是否可以序列化。
EDITx2:看看你的XmlSerializer
,我建议你只是尝试序列化并捕获任何失败。您不一定要直接冒泡。您可以使用自己的自定义异常进行换行,也可以使用返回的结果对象通知API使用者序列化的通过/失败以及可能失败的原因。最好假设调用者正在使用有效对象,而不是每次都进行昂贵的检查。
EDITx3:由于你在save方法中做了很多其他工作,我建议你重写代码:
ObjectStorageHelper
通过这种方式,您可以清楚地捕获序列化问题 ,并且可以非常清楚地向API使用者报告他们提供了无效/不可序列化的对象。这样,如果您将异常作为I / O部分的一部分抛出,则问题在哪里更清楚。实际上,您可能希望将序列化/反序列化方面分离到它们自己的离散方法/类,以便您可以提供其他序列化程序(或者从问题所在的堆栈跟踪中更清楚,或者只是让您的方法执行一个事情和唯一的事情)但是,任何更多的重写/重构实际上都留给了代码审查,对于手头的问题无效。
仅供参考,我还对您的输入对象进行了空检查,因为如果用户传递null,他们会认为保存是成功的,实际上,没有发生并且他们可能期望值为可以在不存在时加载。如果你想允许空值作为有效值,那么不要打扰检查抛出错误。
答案 1 :(得分:2)
这取决于“可序列化”的含义。任何类都可以使用XmlSerializer
序列化。如果您的意思是可以被序列化,那么就不会发生错误,那么您将不得不尝试捕获异常来确定。