设置自定义异常的消息而不将其传递给基本构造函数

Posted

技术标签:

【中文标题】设置自定义异常的消息而不将其传递给基本构造函数【英文标题】:Setting the message of a custom Exception without passing it to the base constructor 【发布时间】:2013-07-15 18:02:46 【问题描述】:

我想在 C# 中创建一个自定义异常,但理论上我确实需要先进行一些解析,然后才能创建人类可读的异常消息。

问题是原始Message只能通过调用Messsage的基构造函数来设置,所以我不能提前做任何解析。

我尝试像这样覆盖 Message 属性:

public class CustomException : Exception

    string _Message;

    public CustomException(dynamic json) : base("Plep")
    
        // Some parsing to create a human readable message (simplified)
        _Message    = json.message;
    

    public override string Message
    
        get  return _Message; 
    

问题在于 Visual Studio 调试器仍然显示我已传递给构造函数的消息,在本例中为 Plep

throw new CustomException( new  message="Show this message"  )

结果:

如果我将基本构造函数留空,它将显示一条非常通用的消息:

App.exe 中出现“App.CustomException”类型的未处理异常

问题

看起来异常对话框读取了一些我也无权访问的字段/属性。有没有其他方法可以在异常的基础构造函数之外设置人类可读的错误消息。

请注意,我使用的是 Visual Studio 2012。

【问题讨论】:

您的代码对我来说工作得很好。它确实有效。 它可以编译,但如果你抛出错误,它将显示底层消息(“Plep”),而不是“显示此消息”。请看一下我添加的额外示例。 我认为没有理想的解决方案。当我将整个异常类解析为 JSON 时,我遇到了类似的问题。自定义属性在此过程中丢失。你能描述一个场景吗?也许我们可以提供一些解决方法。 我试图抛出异常,我有自定义消息,而不是 Pllep Houssem,您使用的是什么 IDE?你在看同一个调试器对话框吗? 【参考方案1】:

只是将格式化代码放入静态方法中?

public CustomException(dynamic json) : base(HumanReadable(json)) 
private static string HumanReadable(dynamic json) 
    return whatever you need to;

【讨论】:

完美!甚至不知道您实际上可以在基本构造函数的参数部分中调用静态方法! 啊.. 必须等待 19 小时才能授予您赏金。很酷,设置赏金确实有效;)【参考方案2】:

考虑创建新例外的 Microsoft 指南:

  using System;
  using System.Runtime.Serialization;

  [Serializable]
  public class CustomException : Exception
  
    //
    // For guidelines regarding the creation of new exception types, see
    //    https://msdn.microsoft.com/en-us/library/ms229064(v=vs.100).aspx
    //

    public CustomException()
    
    

    public CustomException(string message) : base(message)
    
    

    public CustomException(string message, Exception inner) : base(message, inner)
    
    

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

    public static CustomException FromJson(dynamic json)
    
      string text = ""; // parse from json here

      return new CustomException(text);
    
  

注意静态工厂方法(不是模式的一部分),您可以像这样在程序中使用它:

throw CustomException.FromJson(variable);

这样您就可以遵循最佳实践,并且可以在异常类中解析您的 json。

【讨论】:

这行得通.. 但在某种程度上你仍在围绕标准工作。我从来没有通过调用静态方法抛出异常——默认的 .NET 异常也没有调用它们的静态方法。我宁愿不这样做,因为其他程序员不太容易发现它。 评论中的两个链接都已损坏。新链接:Design Guidelines for Exceptions【参考方案3】:

我认为问题可能出在 Visual Studio 调试器上。我得到了与使用调试器相同的结果,但是当我打印消息时:

class CustomException : Exception 
    public CustomException(dynamic json)
        : base("Plep") 
            _Message = json.message;
    

    public override string Message 
        get  return _Message; 
    

    private string _Message;


class Program 
    static void Main(string[] args) 
        try 
            throw new CustomException(new  message = "Show this message" );
         catch (Exception ex) 
            Console.WriteLine(ex.Message);
        
    

我得到了预期的"Show this message"

如果您在捕获异常的位置设置断点,调试器会向您显示正确的消息。

【讨论】:

我知道,但问题确实与 Visual Studio 调试器显示的对话框有关(见屏幕截图)。只是厌倦了(并认为它很丑)不断查看内部异常或其他方式来查看原始消息。【参考方案4】:

这样的事情有什么问题。

    public class FolderNotEmptyException : Exception


    public FolderNotEmptyException(string Path) : base($"Directory is not empty. 'Path'.")
     

    public FolderNotEmptyException(string Path, Exception InnerException) : base($"Directory is not empty. 'Path'.", InnerException)
     


我只使用一个字符串并包含参数。简单的解决方案。

【讨论】:

【参考方案5】:

我喜欢在这里使用它。很简单,不需要静态函数:

public class MyException : Exception

    public MyException () : base("This is my Custom Exception Message")
    
    

【讨论】:

以上是关于设置自定义异常的消息而不将其传递给基本构造函数的主要内容,如果未能解决你的问题,请参考以下文章

如何自动将用户信息传递给 Bot Framework 对话实例,而不将其作为显式消息发布在聊天窗口中?

如何访问对象而不将其作为参数传递?

构造多部分 MIME 消息而不将其保存在内存中

在 CUDA 中查找 max/min 而不将其传递给 CPU

访问非静态类的属性而不将其分配给变量

如何发布数据而不将其传递给模型.Net Core