转让所有权后如何摆脱CA2000警告?
以下代码生成两个CA2000警告(其中,但这不是重点)。
public sealed class Item: IDisposable { public void Dispose() {} } public sealed class ItemContainer { public void Add(Item item) { } } public sealed class Test: IDisposable { private ICollection itemCollection; private ItemContainer itemContainer; private void Add(Item item) { itemCollection.Add(item); } public void Initialize() { var item1 = new Item(); // no warning itemCollection.Add(item1); var item2 = new Item(); // CA2000: call Dispose on object item2 Add(item2); var item3 = new Item(); // CA2000: call Dispose on object item3 itemContainer.Add(item3); } public void Dispose() {} }
请注意,item1没有生成警告。 似乎,代码分析假设ICollection
将负责该项目并最终处置它。
有没有办法标记我的Add
方法,以便警告消失?
我正在寻找类似于CA1062的ValidatedNotNullAttribute
的东西。
编辑:说清楚:这不是我真正的代码。 在真实的代码中,一切都妥善处理。
只是CA无法识别对Add
方法的调用会转移所有权。 我希望它以与处理ICollection.Add
相同的方式处理我的Add方法。
处置相同的范围不是一种选择。
您想修复代码还是只是禁止警告? 抑制警告很简单:
[SuppressMessage("Microsoft.Reliability", "CA2000:DisposeObjectsBeforeLosingScope", Justification = "Your reasons go here")] public void Initialize() { // ... }
我也在connect.microsoft.com上问了这个,这就是他们回答的问题:
您可以通过使添加一次性对象的容器/集合对象实现ICollection或ICollection
当然,当类Test实现ICollection
public sealed class Test: IDisposable, ICollection- { public void Initialize() { var item1 = new Item(); // no warning itemCollection.Add(item1); var item2 = new Item(); // no warning ((ICollection
- )this).Add(item2); var item3 = new Item(); // no warning AddSomething(item3); } //... implement ICollection and Method AddSomething }
我知道这是示例代码,因此这种解决方法是否适用于您的实际代码,我不能说。
在这种特殊情况下,如果将对象创建代码移动到它自己的方法中,返回新的Item,则警告将消失,例如更改:
public void Initialize() { var item1 = new Item(); // no warning itemCollection.Add(item1); var item2 = CreateItem(); // CA2000 no longer appears Add(item2); var item3 = new Item(); // CA2000: call Dispose on object item3 itemContainer.Add(item3); } private Item CreateItem() { return new Item(); }
显然,CreateItem方法可以传递任意参数传递给Item构造函数。
编辑
看过Henrik的回答,以及对Connect的回应,我只能说是bletch 。 不能保证ICollection实现也实现了IDisposable,虽然他发布的示例确实实现了IDisposable,但显然不需要关闭代码分析(如果你必须同时实现两者,我会有所帮助)。 实现ICollection但未实现IDisposable的类极不可能正确处理包含的对象。
当然,首先要做的是实际让Dispose方法清理集合的成员。 我假设这只是示例中的错误,而不是真正的代码。
除此之外,我会压制警告。 我坚决认为任何压制:
- 应该是一个非常短的范围,所以它不会抑制另一个警告的情况,这是一个真正的错误。
- 应该注释注释,无论多么明显的脑死亡,似乎警告是安全的压制。
也就是说,我认为对CA2000的分析是如此之差,以至于不值得在默认情况下进行检查,但仅限于偶尔的评论。 在一定数量的误报后,警告甚至不能被视为警告,只是噪音隐藏了真正的警告,因此使代码更容易出错。