PCL 文件中的自定义异常

Posted

技术标签:

【中文标题】PCL 文件中的自定义异常【英文标题】:Custom Exceptions in PCL files 【发布时间】:2015-11-12 19:05:45 【问题描述】:

我目前正在将我们的 .net 业务对象库转换为 PCL 文件,以便它可以与 Xamarin ios/android 一起使用,虽然它主要包含 POCO 对象,但它也包含自定义异常,但这会引发错误。

采用典型的自定义异常:

[Serializable]
public class EncryptKeyNotFoundException : Exception

    public EncryptKeyNotFoundException()
        : base()  

    public EncryptKeyNotFoundException(string message)
        : base(message)  

    public EncryptKeyNotFoundException(string format, params object[] args)
        : base(string.Format(format, args))  

    public EncryptKeyNotFoundException(string message, Exception innerException)
        : base(message, innerException)  

    public EncryptKeyNotFoundException(string format, Exception innerException, params object[] args)
        : base(string.Format(format, args), innerException)  

    protected EncryptKeyNotFoundException(SerializationInfo info, StreamingContext context)
        : base(info, context)  

正如预期的那样,PCL 不喜欢[Serializable]SerializationInfo。虽然我可能会坚持 [DataContract] 而不是使用[Serialiable],但它仍然无法解决SerializationInfo 的问题。

有没有办法规避这个问题?

谢谢。

更新:

我按照建议查看了Implementing custom exceptions in a Portable Class Library,但无法识别以下 2 个属性:

[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComVisibleAttribute(true)]

我一定是缺少一个引用,但是是哪个程序集?

我目前正在寻找Portable class library: recommended replacement for [Serializable] 中提供的替代解决方案

希望这会奏效。一旦我有更多信息可以提供,我会更新我的答案。

更新:

ClassInterfaceAttribute 是 System.RunTime.InteroServices 的一部分,但我无法将其添加到我的 PCL 项目中,至少它不可见。我错过了什么吗?

另一篇文章提供了额外的信息,看起来在使用条件编译时,这应该可以工作,但同样,虽然 json 库中的示例代码似乎可以工作,但我必须遗漏一些东西,因为我无法添加参考所以[Serializable] 不会引发错误,但我似乎无法这样做。

我尝试过的一件事是简单地注释掉:

protected EncryptKeyNotFoundException(SerializationInfo info, 
StreamingContext context) : base(info, context)  

我可以编译我的 pcl 项目了,所以问题是我需要这个吗?

谢谢。

【问题讨论】:

我认为这对你有帮助Implementing custom exceptions in a Portable Class Library 我找到了这篇文章,但认为它不相关。完成后我会试一试并更新。谢谢。 我已经更新了我的答案,但不幸的是,它没有帮助。我错过了什么吗? 从您的更新看来,您误解了建议的答案。我不能在评论中添加太多解释,所以在答案中添加。 【参考方案1】:

我认为您误解了建议链接中的答案。您无需在自定义异常实现中添加ClassInterfaceAttributeComVisibleAttribute。如果我们查看Exception class for .NET Framework,我们会看到:

[SerializableAttribute]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComVisibleAttribute(true)]
public class Exception : ISerializable, _Exception

在Exception class for Silverlight,这个

[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ComVisibleAttribute(true)]
public class Exception

SerializableAttribute 不可用。

另一个区别是 Silverlight 的 Exception 类只有 3 个构造函数。 构造函数Exception(SerializationInfo, StreamingContext) 不可用。我们还可以在下面的 PCL 库中自定义异常实现的屏幕截图中看到,只有 3 个构造函数可用于异常。 没有您尝试创建的可用构造函数:

EncryptKeyNotFoundException(SerializationInfo info, StreamingContext context)
   : base(info, context)  

因此,在使用 DataContract 而不是 Serializable 的 PCL 自定义异常实现中,将是这样的:

[DataContract]
public class EncryptKeyNotFoundException : System.Exception

    public EncryptKeyNotFoundException() : base()  

    public EncryptKeyNotFoundException(string message) : base(message)  

    public EncryptKeyNotFoundException(string message, Exception innerException) : base(message, innerException)  

【讨论】:

嗨 Mak,感谢您的详细说明。如果您查看我更新的问题,这就是我最终要做的,即摆脱使用 SerializationInfo 的重载方法。 是的,您最终得到了可行的解决方案,但我认为这有助于理解为什么会这样。 :) 完全同意你的看法,谢谢!今天学习新东西!

以上是关于PCL 文件中的自定义异常的主要内容,如果未能解决你的问题,请参考以下文章

Java:简述Java中的自定义异常

Spring Boot 中的自定义异常

在Java中的自定义异常中序列化字段

Grails 中的自定义验证器中的异常

为 Java 中的自定义检查异常编写 JUnit 测试用例?

处理主脚本中的自定义异常