确保方法 return 值未被库丢弃

Ensure that method return value is not discarded for library

我的库有一些方法,其 return 值永远不应被丢弃。泄露它们是一个非常普遍的错误,即使对我,作者也是如此。所以我希望编译器在这样做时提醒程序员。

这样的值可以被存储或用作另一个方法的参数。不是严格使用存储的值,但如果简单地丢弃它是 100% 错误。

是否有任何易于设置的方法来为我的图书馆用户强制执行此操作?

var x = instance.Method(); // ok
field = instance.Method(); // ok
instance.OtherMethod(instance.Method()); // ok
MyMethod(instance.Method()); // ok, no need to check inside MyMethod
instance.Method(); // callvirt and pop - error!

我考虑过为 post-build 事件制作 IL 分析器,但感觉太复杂了...

如果您实施 Code Analysis / FXCop, the rule CA1806 - 不要忽略方法结果 将涵盖这种情况。

参见:How to Enable / Disable Code Analysis for Managed Code

基本上,它就像转到项目文件、代码分析选项卡、选中一个框并选择要出错/警告的规则一样简单。

基本上勾选复选框 @ 1,然后使用 2 进入 window,您可以在其中配置规则集文件(这可以是您在库之间共享的文件,也可以是更全局的文件(如果您有一个构建服务器,确保它存储在构建可以到达的某个地方,即源不在本地机器上)。

这是一个规则集,我的意思是:

Nicolai 的回答为任何类型启用了规则集,但我只需要对我的库类型进行此检查(我不想强迫我的库用户在他们的所有代码上应用规则集)。

按照评论中的建议到处使用 out 会使库的使用变得困难。

因此我选择了另一种方法。

  1. 在终结器中,我检查是否调用了任何方法(这足以让我确认使用情况)。如果不是 - InvalidOperationException。可选择记录对象创建 StackTrace 并将其附加到错误消息中。
  2. 用户可以调用 SetNotLeaked() 以递归方式禁用对特定对象和所有内部对象的检查。

这不是编译时检查,但肯定会被注意到。

这不是一个非常优雅的解决方案,它违反了一些准则,但它满足了我的需要,不会让用户查看不必要的警告(RuleSet 解决方案)并且不会影响代码清洁度(out)。

为了测试,我必须创建一个基础 class,我在 SetUp 方法中设置 Appdomain.UnhandledException 处理程序并检查(在 GC.Collect 之后)是否抛出了任何异常TearDown 因为终结器是从另一个线程调用的,否则 NUnit 会显示测试已通过。