C#:重写自定义异常的 ToString() 方法
我有一个自定义异常类,其中包含一些附加字段。我希望将它们写在 ToString()
方法中,但是如果我实现自己的 ToString()
,我会丢失一些其他有用的东西(例如编写异常类型)名称、内部异常数据和堆栈跟踪)。
针对此类异常实现您自己的 ToString()
方法的最佳方式/模式是什么?理想情况下,它应该重用现有的机制,但以类似于默认 ToString()
实现的方式进行格式化。
更新:将我的自定义字段添加到 base.ToString() 文本中并不理想,恕我直言,例如
PimTool.Utilities.OERestServiceUnavailableException: test ---> System.InvalidOperationException: inner message
--- End of inner exception stack trace ---
at PimTool.Tests.Services.OE.OERestClientTests.ExceptionsLogging() in D:\svn\NewPimTool\PimTool.Tests\Services\OE\OERestClientTests.cs:line 178,
StatusCode=0, message='test', requestId='535345'
意味着自定义字段写在(可能很长)异常描述的末尾。 另一方面,我希望异常类型成为描述中写入的第一个信息。
更新2:我已经为此实现了一个解决方案,请在下面查找我自己的答案。
I have a custom exception class which contains some additional fields. I want these to be written out in the ToString()
method, but if I implement my own ToString()
, I loose some other useful stuff (like writing the exception type name, the inner exception data and the stack trace).
What is the best way/pattern to implement your own ToString()
method for such exceptions? Ideally it should reuse the existing mechanism, but be formatted in way similar to the default ToString()
implementation.
UPDATE: prepending or appending my custom fields to the base.ToString() text isn't ideal IMHO, for example
PimTool.Utilities.OERestServiceUnavailableException: test ---> System.InvalidOperationException: inner message
--- End of inner exception stack trace ---
at PimTool.Tests.Services.OE.OERestClientTests.ExceptionsLogging() in D:\svn\NewPimTool\PimTool.Tests\Services\OE\OERestClientTests.cs:line 178,
StatusCode=0, message='test', requestId='535345'
means the custom fields are written at the end of the (potentially long) exception description.
On the other hand, I want the exception type to be the first information written in the description.
UPDATE 2: I've implemented a solution for this, look for my own answer below.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
这一切都太过分了。您的异常应该只覆盖 Message 属性。
Exception 类的默认 ToString 方法基本上是“
ClassName: Message --> InnerException.ToString() StackTrace
”。因此,覆盖消息会将消息文本准确地放置在应有的位置。This is all overkill. Your exception should just override the Message Property.
The default ToString method for the Exception class is basically "
ClassName: Message --> InnerException.ToString() StackTrace
". So overriding the Message puts your message text exactly where it should be.好的,这就是我想出的。我已经实现了一个扩展类,它复制了格式化异常的原始机制,但有一个变化:一个自定义 Action 委托,它提供了一个用于格式化自定义字段的插件:
现在您可以在自己的 ToString() 实现中使用此方法,而无需复制格式化代码:
OK, this is what I came up with. I've implemented an extension class which replicates the original mechanism for formatting exceptions, but with a twist: a custom Action delegate which provides a plug-in for formatting custom fields:
Now you can use this method in your own ToString() implementations without duplicating the formatting code:
您可以通过查看异常属性,手动将默认数据添加到
ToString
返回的字符串中。例如,以下内容将模拟异常的ToString
方法默认返回的数据(假设没有内部异常):或者,您可以简单地附加(或前置)由
返回的数据base.ToString
到您要添加的信息。You could manually add the default data to the string returned by
ToString
, by looking at the exception properties. For example, the following will simulate the data returned by default by a exception'sToString
method (assuming there are no inner exceptions):Or, you could simply append (or prepend) the data returned by
base.ToString
to the information you want to add.您可以重写 ToString() 方法以包含您自己的自定义信息,并且仍然调用默认的基本 Exception ToString(),如下所示:
You can override the ToString() method to include your own custom information, and still call the default base Exception ToString() like this:
如果您主要在调试器中查看它们,则可以使用
[DebuggerDisplay]
属性来指定它们的格式,而不需要触及现有的ToString
方法。否则,只需重载
ToString
并确保调用基类版本base.ToString()
If you're primarily looking at them in the debugger, then you can use the
[DebuggerDisplay]
attribute to specify their formatting and not touch the existingToString
method.Otherwise, just overload
ToString
and be sure to call the base class versionbase.ToString()
最简单的方法
The simplest way
在覆盖内部调用 base.ToString() 并根据您的需要修改生成的字符串...
Inside the override call base.ToString() and modify the resulting string to your needs...
与Glinko的答案类似的想法是在基本字符串的第一行之后插入变量,但实现有点不同:
Similar idea to Glinko's answer of insertion of your variables after the first line of base string, a bit different implementation: