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

C# 设置自定义异常的消息而不将其传递给基构造函数,c#,visual-studio,exception,visual-studio-2012,C#,Visual Studio,Exception,Visual Studio 2012,我想在C#中生成一个自定义异常,但理论上,在生成一个人类可读的异常消息之前,我确实需要先进行一些解析 问题是原始消息只能通过调用Message的基本构造函数来设置,因此我无法提前进行任何解析 我试图像这样覆盖Message属性: public class CustomException : Exception { string _Message; public CustomException(dynamic json) : base("Plep") {

我想在C#中生成一个自定义异常,但理论上,在生成一个人类可读的异常消息之前,我确实需要先进行一些解析

问题是原始消息只能通过调用
Message
的基本构造函数来设置,因此我无法提前进行任何解析

我试图像这样覆盖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; }
    }
}
throw CustomException.FromJson(variable);
问题是VisualStudio调试器仍然显示我传递给构造函数的消息,在本例中为Plep

throw new CustomException( new { message="Show this message" } )
结果:

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

App.exe中发生类型为“App.CustomException”的未处理异常

问题

异常对话框似乎读取了一些我没有任何访问权限的字段/属性。是否有任何其他方法可以在基本构造函数之外的异常上设置人类可读的错误消息


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

请考虑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);
    }
  }
请注意静态工厂方法(不是模式的一部分),您可以在程序中这样使用:

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; }
    }
}
throw CustomException.FromJson(variable);

这样,您就遵循了最佳实践,可以在exception类中解析json。

是否将格式化代码放入静态方法

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

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

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);
        }
    }
}
我得到了预期的
“显示此消息”


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

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

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

这样的东西怎么了

    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)
    { }

}

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

这将起作用。。但在某种程度上,您仍然在围绕标准工作。我从未通过调用静态方法引发过异常-默认的.NET异常也没有静态方法来调用它们。我不想这样做,因为其他程序员不太容易发现。评论中的两个链接都断了。新链接:你的代码对我来说很好。它可以编译,但如果你抛出一个错误,它将显示底层消息(“Plep”),而不是“显示此消息”。请看一看我添加的额外示例。我认为理想的解决方案不可用。当我将wholoe异常类解析为JSON时,遇到了类似的问题。自定义属性在此过程中丢失。你能描述一个场景吗?也许我们可以帮助解决一些问题。我试图抛出异常,我有一个自定义消息,我放在那里,而不是PllepHoussem,你在用什么IDE?您是否正在查看同一个调试器对话框?我知道,但问题确实与Visual Studio调试器显示的对话框有关(请参见屏幕截图)。只是厌倦了(觉得很难看)不断地查看内部异常或其他方式来查看原始消息。太棒了!甚至没有意识到您实际上可以在基本构造函数的arguments部分中调用静态方法!啊。。我得等19个小时才能给你赏金。很酷,设置悬赏确实有效;)