使用带有内部异常的构造函数的正确方法

Posted

技术标签:

【中文标题】使用带有内部异常的构造函数的正确方法【英文标题】:Correct way to use constructor with inner exception 【发布时间】:2022-01-06 04:17:22 【问题描述】:

假设我有一个带有用户定义异常的典型应用程序,当文件无法处理时抛出该异常。异常包含用户友好的错误消息。

[Serializable]
public class ProcessingFileException : Exception

    public ProcessingFileException()  
    public ProcessingFileException(string message) : base(message)  
    public ProcessingFileException(string message, Exception inner) : base(message, inner)  
    protected ProcessingFileException(SerializationInfo info, StreamingContext context) : base(info, context)  
    override public string Message => "Error occurred while file processing...";


public class Program

    private void DoSomeWithFile() 
        // some action
    

    public void Main(string[] args) 
        try
        
            DoSomeWithFile();
         
        catch (Exception ex)
        
            throw new ProcessingFileException("Error occurred while file processing...", ex);
        
    

现在我想抛出我的用户定义异常并将原始异常作为内部异常传递。但是强制构造函数要求我将消息和内部异常一起传递How to create user-defined exceptions。

catch (Exception ex)

    throw new ProcessingFileException("Error occurred while file processing...", ex);

我不想在我的代码中重复消息文本。消息已在我的异常中定义。

如何使用原始消息创建用户定义的异常并捕获内部异常。解决此问题的最佳设计或方法是什么?

【问题讨论】:

使用ex.Message? 只要定义你要定义的构造函数即可。它们都不是“强制性的”。一种指定/增加异常消息以将其传递给基本 ctor 而不是覆盖Message 的常用方法,例如base($"Error occurred while ...: inner.Message", inner) 你为什么要覆盖Message?您应该通过构造函数将其设置为您想要的值。 您可以添加自己的构造函数来初始化消息:public EmployeeListNotFoundException(Exception inner): base("My message", inner) 【参考方案1】:

但强制​​构造函数需要我一起传递消息和内部异常

没有强制构造函数。您可以定义对特定异常类型有意义的任何构造函数。添加自定义参数也很常见(例如 ResponseStatusCode 用于 HTTP 相关的异常)。

这很简单:

public class ProcessingFileException : Exception

    private const string _message = "Error occurred while processing file...";

    public ProcessingFileException() : base(_message)
    
    

    public ProcessingFileException(Exception inner) : base(_message, inner) 
    
    

通常不需要其他构造函数,[Serializable] 也不太可能有用。

【讨论】:

Serializable 在 .NET Framework 中很有用,因为可能会跨 AppDomain 引发异常。 NET Core / .NET 5+ 没有 AppDomains,所以Serializable 没用 @canton7 异常序列化仍然有用 - 例如,当HttpWebRequest 抛出异常并且需要将异常序列化回客户端(反之亦然)时 谢谢。而不是“private const string _message =>”应该是“private const string _message =”。 您的代码现在的第一个重载似乎不合法。 Message 没有(可见的)set 访问器。你应该做: base(_message) 类似于你在另一个重载中所做的事情。或者,执行: this(_message, null) 感谢@JeppeStigNielsen,已修复 - 这是在没有 IDE 的情况下编写代码的问题 :) 我

以上是关于使用带有内部异常的构造函数的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

此类未定义公共默认构造函数,或构造函数引发异常。内部异常:java.lang.InstantiationException

从匿名内部类的构造函数中抛出异常

C++的构造函数可以抛出异常么

如何处理构造函数的失败?

为内部子接口创建“默认构造函数”

在构造函数中抛出 ArgumentNullException?