为啥我应该总是让我的异常[可序列化]? (。网)

Posted

技术标签:

【中文标题】为啥我应该总是让我的异常[可序列化]? (。网)【英文标题】:Why should I always make my Exceptions [serializable]? (.NET)为什么我应该总是让我的异常[可序列化]? (。网) 【发布时间】:2010-11-07 04:36:23 【问题描述】:

参考What is the correct way to make a custom .NET Exception serializable? 和Are all .NET Exceptions serializable? ...

为什么我的异常应该是可序列化的? 有人说,如果第三方库定义的自定义异常是不可序列化的,“它可以被认为是一个错误”。为什么?

为什么在这方面异常与其他类不同?

【问题讨论】:

【参考方案1】:

因为您的异常可能需要在不同的 AppDomain 之间进行编组,如果它们不能(正确)序列化,您将丢失宝贵的调试信息。与其他类不同,您无法控制是否对异常进行编组——它会。


当我的意思是“你将无法控制”时,我的意思是你创建的类通常具有有限的存在空间,并且存在是众所周知的。如果它是一个返回值并且有人试图在不同的 AppDomain(或在不同的机器上)调用它,他们会得到一个错误,并且可以说“不要那样使用它”。调用者知道他们必须将其转换为可以序列化的类型(通过包装方法调用)。但是,由于如果没有被捕获,异常就会冒泡到最顶端,它们可以超越您甚至不知道的 AppDomain 边界。您在不同 AppDomain 中的 20 级自定义应用程序异常可能是 Main() 报告的异常,并且在此过程中没有任何东西可以将其转换为您的可序列化异常。

【讨论】:

你能想出一个实际发生这种情况的具体情况/例子吗? @Sam:默认情况下,NUnit 会创建一个或多个单独的 AppDomain,以便将您的代码与 NUnit 运行程序本身隔离开来,并且可以合理地期望其他单元测试框架也这样做。 【参考方案2】:

除了 Talljoe 的回答之外,您的异常也可以通过 Web 服务传递,在这种情况下,异常需要可序列化/可反序列化,以便可以将其转换为 XML 并由 Web 服务传输

【讨论】:

杰弗里:你几乎是正确的。当通过 Web 服务“发送”异常时,不一定要对所有异常进行序列化。它实际上被转换为 SOAP 故障,因此不需要完全保真。此外,旧 ASMX 服务中使用的 XML Serializer 很少或根本不关注 [Serializable]。【参考方案3】:

我认为所有类的默认值都应该是可序列化的,除非它们包含一个明确不可序列化的类。只是因为一些设计师没有考虑,所以不能转移一个类是很烦人的。

与“Final”相同,默认情况下所有变量都应为“Final”,除非您明确说明它们是“Mutable”。

另外,我不确定拥有一个非私有变量是否有意义。

哦,好吧,需要设计我自己的语言。

但答案是,您不知道如何使用您的异常,并且假定它们能够跨远程调用抛出。

【讨论】:

@Bill:或者,设计师确实考虑过,但决定不支持序列化。例如,如何序列化一个持有原生资源句柄的类,甚至只是打开流? 异常不需要这样做。此外,我在上个月遇到并想要序列化的 3 个课程(包括一个例外)没有任何此类限制。设计不可更改 API 的委员会根本没有这样规定 哦,至于我的默认可序列化建议,如果您有这些条件,资源将被标记为“不可序列化”,这将链接到您的类,使其不可序列化,除非您将它们标记为“瞬态” ",所以它会工作得很好——比当前的系统更好。 有趣的意见。我了解异常旨在远程处理,这需要[可序列化]。但是问题的第二部分呢:为什么异常与任何其他类都不同? wrt [可序列化]?引发异常的类是不可序列化的,似乎没有人对此表示怀疑。 抛出异常的类有一个合理的期望,它不会被远程(因为我刚刚实现了一大堆臭气熏天的 RMI,我可以告诉你,这并不总是正确的,但在一般是这样)。除了一个例外,你必须知道你上面的所有类才能知道这是真的。通过使未经检查的异常可序列化,您可以以奇怪的方式随机破坏远程代码,而几乎无法弄清楚发生了什么(在客户端,它可能看起来就像您的调用永远不会返回 - 永远。我不得不追逐其中一个下来,这很WTF)。【参考方案4】:

另一个需要可序列化对象的地方是 Asp.Net Session。 我们将最后一个异常存储在 Session 中,不可序列化的异常需要额外的翻译才能将其详细信息存储为可序列化(将原始异常指定为内部没有帮助)

【讨论】:

这听起来像是在 your 用例中需要对异常进行 sdrializable 的原因,但它并不能真正回答一般问题。 @stakx,当你修改代码时,你应该考虑不同的用例,它可以在哪里使用

以上是关于为啥我应该总是让我的异常[可序列化]? (。网)的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的异常类需要序列化?

为啥网络总是异常中断?

为啥我不应该让一个类可序列化?

为啥我的Myeclipse9.0总是激活失败

为啥我的MacBook air 在app里下载软件总是失败,让我返回已购页面再试一次?

Centos的时间问题. 为啥我的时间总是异常,,每10几秒总会比正常时间快几秒?