Hen*_*rik 15 c# code-analysis visual-studio-2010
以下代码生成两个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<Item> 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() {}
}
Run Code Online (Sandbox Code Playgroud)
请注意,item1没有生成警告.似乎,代码分析假定ICollection遗嘱将对该项目负责并最终处置它.
有没有办法标记我的Add方法,以便警告消失?
我正在寻找类似于ValidatedNotNullAttributeCA1062的东西.
编辑:说清楚:这不是我的真实代码.在真实的代码中,一切都妥善处理.
只是CA无法识别对我的Add方法的调用转移所有权.我希望它以与处理相同的方式处理我的Add方法ICollection.Add.
处置相同的范围不是一种选择.
Luk*_*keH 11
您想修复代码还是只是禁止警告?抑制警告很简单:
[SuppressMessage("Microsoft.Reliability",
"CA2000:DisposeObjectsBeforeLosingScope",
Justification = "Your reasons go here")]
public void Initialize()
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
我知道这是示例代码,因此这种解决方法是否适用于您的实际代码,我不能说.
在这种特殊情况下,如果将对象创建代码移动到它自己的方法中,则返回新的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();
}
Run Code Online (Sandbox Code Playgroud)
显然,CreateItem方法可以传递任意参数传递给Item构造函数.
编辑
看过Henrik的回答,以及对Connect的回应,我只能说是bletch.不能保证ICollection实现也实现了IDisposable,虽然他发布的示例确实实现了IDisposable,但显然不需要关闭代码分析(如果你必须同时实现两者,我会有所帮助).实现ICollection但未实现IDisposable的类极不可能正确处理包含的对象.
我也在connect.microsoft.com上问了这个,这就是他们回答的问题:
您可以通过使添加一次性对象的容器/集合对象实现ICollection或ICollection <T>来解决此问题.执行Add的方法也必须具有以"Add"开头的名称.
当然,当类Test实现ICollection <Item>时,警告就会消失.对于相关案例,这是一个可接受的解决方案.但是,如果不适合实施ICollection以表明所有权转移,那么这仍然是一个悬而未决的问题.
public sealed class Test: IDisposable, ICollection<Item>
{
public void Initialize()
{
var item1 = new Item(); // no warning
itemCollection.Add(item1);
var item2 = new Item(); // no warning
((ICollection<Item>)this).Add(item2);
var item3 = new Item(); // no warning
AddSomething(item3);
}
//... implement ICollection and Method AddSomething
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
11088 次 |
| 最近记录: |