【问题标题】:Attribute to inform method caller of the type of exceptions thrown by that method用于通知方法调用者该方法抛出的异常类型的属性
【发布时间】:2013-05-17 23:57:51
【问题描述】:

我不打算实现 Java“throws”关键字。请参阅http://www.artima.com/intv/handcuffsP.html,讨论 throws 关键字的优点以及为什么它没有在 C# 中实现。

不过,我很好奇是否有办法创建如下所示的属性:

[ThrowsException( exceptionType = NullReferenceException )] 
[ThrowsException( exceptionType = AuthenticationException )]
public void Login( Credentials credz ) 
{
    // ... etc...
}

这样 - 当调用一个使用一个或多个 ThrowsException 属性修饰的方法时,该方法抛出的异常类型(至少是由 ThrowsException 属性显式声明的异常类型)将在方法的文档中可见

这与 Java 的“throws”关键字不同,因为它不需要调用者处理这些异常。这样做可能会引入重大更改,例如在不处理版本更改引入的新异常的客户端应用程序中。

虽然可以使用:

/// <exception cref="member">description</exception>

我使用属性的意图是,如果异常名称已更改或异常不再存在,则项目不会编译。所以How To Document Thrown Exceptions,不是同一个问题。


更新:2013-05-23

我想出了一种通过使用属性而不使用插件来解决的方法。我将在本周末尝试解决它,如果它按预期工作,我很乐意发布解决方案。如果有人击败我发布解决方案,我会很乐意接受他们的回答。

由于我要到星期一才能解决这个问题,如果你能打败我,我会提供赏金 - 一个可以接受的答案是:

  • (不包括使用 Visual Studio 插件或任何第三方工具
  • && 提供了一种在 XML 文档中包含异常的方法
  • && 确保在编译期间强制执行类型安全)
  • ||证明不可能满足上述三个要求才能解决此问题中提出的问题

我认为 XML 文档不反映异常是可以接受的,从 ThrowsException 属性开始,直到项目构建完成。

看到基于 Resharper 的解决方案会很有趣(因为它在我工作过的大多数开发商店中都很常见),但如果存在与第三方工具无关的解决方案,它将不会被接受.同样,仅适用于 Visual Studio 的解决方案将被接受,而不是依赖于 Resharper 的解决方案,但如果存在适用于其他 IDE 的解决方案,则不会被接受,例如MonoDevelop(支持更多框架——甚至更好)。

【问题讨论】:

  • 你的意思是这样? stackoverflow.com/questions/461306/…
  • 我已经增加了清晰度,为混乱道歉
  • XML cmets 默认会添加到 XML 文档中。您将需要一个 VS 插件来使属性在智能感知中可见。已经有一些关于写这类东西的不错的 SO 问题了。
  • 这个问题不应该被关闭,它被标记为stackoverflow.com/questions/461306/… 的重复,而我明确说明不是这样的

标签: c# exception custom-attributes


【解决方案1】:

以下应该可以工作

[ThrowsException( ExceptionType = typeof(NullReferenceException) )]

您的属性将具有Type 类型的属性

Type ExceptionType { get; set; }

【讨论】:

  • 实现该属性是微不足道的。挑战在于让它做一些有用的事情。
  • 自从他解决了 OP 的问题以来,我认为没有理由投反对票。
  • "当调用一个用 [a] ThrowsException 属性修饰的方法时,该方法抛出的异常类型......将在方法的文档中可见"
  • @Yaur - 是的,这意味着什么?
  • @JakubKonecki 我的假设是他希望它们在标准 xml docs/intellisense 中可见。
【解决方案2】:

在 C# 中,您使用 XML 文档记录类及其成员。在 Visual Studio 中,开始在某些内容上输入斜杠,到第三个斜杠时,它会自动生成最常见的标签供您填写。它看起来有点像 Javadoc 和 JSDoc。

您正在寻找,特别是this tag

【讨论】:

  • 我必须为我的不明确表示歉意。我将修改这个问题 - 我使用属性的意图是,如果异常名称已更改或异常,项目将无法编译不再存在
  • @Martin 如果你写例如/// &lt;exception cref="DivideByZeroException"&gt;Why it's thrown.&lt;/exception&gt;,如果您在编译项目时实际构建了 XML 文档,那么如果范围内的命名空间中不存在名为 DivideByZeroException 的类,您将收到编译时错误。
  • @JeppeStigNielsen - 也许我需要设置另一个选项,但我正在生成 XML 文档,并且它正在编译没有问题
  • @Martin 您是否按照页面/doc (C# Compiler Options) 上的在Visual Studio 开发环境中设置此编译器选项部分中的操作?
  • @280Z28 你是对的。原始发帖人可以选择将此特定警告视为错误,或将所有 个警告(可能是高于某个级别的所有警告)视为错误。请参阅此MSDN page on warning level,了解有关如何从命令行或在 Visual Studio 中完成此操作的信息。
【解决方案3】:

我使用属性的意图是使项目无法编译 如果异常名称已更改或异常没有 不再存在。因此,如何记录抛出的异常不是 同样的问题。

您可以在不使用属性的情况下执行此操作,而是通过编写 <exception> 文档并像这样配置您的项目:

Project properties -> 'Build' tab:
'Output' section: Check 'XML documentation file'.
'Treat warnings as erros' section: Check 'Specific warnings' and add warning 1574.

如果无法解析 XML 文档 cref 属性值,则项目将无法编译。

【讨论】:

  • 这是目前为止最好的答案,如果在 6 天赏金结束时没有更好的答案,我会接受。我对此有一些问题: 1. 它特定于 Visual Studio 2。它需要在项目级别应用 3。这适用于所有带有 cref 语句的 cmets,例如我正在开发一个 WPF 项目,我在其中使用来自 MVC 的数据注释,并且我有一条评论解释说您可以将 AspMvcActionAttribute 用于类似于 显然没有被引用。
  • 1.它不特定于 Visual Studio,您也可以直接在 C# 编译器中指定所有这些选项。 2.正确,适用于可编译单元,即项目。 3.正确,它适用于所有具有cref属性的cmets。但是为什么要将 cref 属性与未引用的东西一起使用呢?编译器无法帮助验证值是否正确,文档工具也无法生成指向 cref 值的超链接。
  • @Martin 关于您的第 3 项:您可以添加对 System.Web.Mvc.dll 的项目引用,以便在生成文档时解决 cref。如果您没有从代码中引用该程序集的任何成员,那么最终编译的程序集实际上会省略该引用,因此您不会留下不需要的程序集... [注释太长,请参阅下一个... ]
  • @Martin [...接上一页] 为防止从代码中意外创建对此程序集的引用,请在 Visual Studio 属性窗格中设置 Aliases 字段以引用类似 mvc 的内容.在文档中需要引用该程序集的具体文件中,在文件顶部添加extern alias mvc;,然后在文档中以&lt;see cref="mvc::System.Web.Mvc.Html.ChildActionExtensions.RenderAction(mvc::System.Web.Mvc.HtmlHelper, string)"/&gt; 引用。
  • 好吧,虽然我仍然认为有更好的方法可以在代码中做到这一点,但过去两周我每天工作 16 小时,所以我没有时间解决它......所以赏金给你 :) 如果你问我,这个问题很简单;)但我从来没有发布过赏金,所以我认为它会很有趣。
猜你喜欢
  • 2013-01-01
  • 2017-05-31
  • 1970-01-01
  • 1970-01-01
  • 2012-11-22
  • 2011-10-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多