【发布时间】:2017-04-07 10:41:50
【问题描述】:
FxCop 警告“具有一次性字段的类应该是一次性的”有时让我感到困惑。请参阅下面的人为示例
只有一种类型创建并拥有一次性资源,但任何数量的类型都可以使用(或“借用”)该资源。我看到开发人员在 Util1 和 Util2 上收到 FxCop 警告,表明由于他们有一个一次性类型的字段,他们必须实现 Dispose 并处置该字段。这显然不是你想要的。
有问题吗
创建只借用一次性资源的类是一种反模式。一次性资源可以作为方法参数传递给 Util1 和 Util2,问题就会消失。只有创建一次性资源的类才应该将它们作为字段,以便字段本身表明所有权。
警告不够巧妙。当 拥有 一次性资源的类型本身不是一次性资源时,它应该发出警告,在这种情况下,只有一个类拥有它,而其他类则借用它。它仅从构造函数参数注入的事实可以被更聪明的规则用来检测不应为借用类引发警告。
还有别的吗?
static class Program
{
public static void Main()
{
using(var r = new SomeResource())
{
Console.WriteLine(new Util1(r).Foo());
Console.WriteLine(new Util2(r).Foo());
}
}
}
public sealed class SomeResource : IDisposable
{
private readonly NativeResource native;
public void SomeResource()
{
native = Native.CreateDisposableThing();
}
public void Dispose()
{
native.Dispose();
}
}
public sealed class Util1 {
private readonly SomeResource res;
public Util1(SomeResource res) { this.res = res; }
public string Foo() { /* uses res */ }
}
public sealed class Util2 {
private readonly SomeResource res;
public Util2(SomeResource res) { this.res = res; }
public string Foo() { /* uses res */ }
}
【问题讨论】:
-
嗯,这只是静态分析,它可能是对的,也可能是错误的。它无法知道您是否拥有或借用该资源,因此如果您知道自己在做什么 - 只需针对这种特殊情况禁用此警告。从您提供的选项来看,我认为 2 是正确的。
-
我猜是#2
-
我也相当确定它是 #2,但考虑到制定规则似乎很容易,至少忽略 IDisposable 仅注入到 ctor 的类型,我真的很好奇它是否还有更多内容。