请考虑以下代码:
public class Test
{
public async Task Do()
{
await Task.Delay(200);
using (var disposable = new Disposable())
{
disposable.Do();
}
}
}
public class Disposable : IDisposable
{
public void Do()
{
}
public void Dispose()
{
}
}
当我在Visual Studio中运行代码分析时,我收到警告:
警告CA1001在测试时实施IDisposable。<请执行> d__0,因为它会创建以下IDisposable类型的成员:' Disposable'。
为什么我会收到此消息?一次性课程处理正确,我不会将其存放在任何地方。
此外,分析器似乎没问题:
public class Test
{
public void Do()
{
using (var disposable = new Disposable())
{
disposable.Do();
}
}
}
答案 0 :(得分:28)
那是因为编译器从您的异步方法生成状态机,并且该状态机类(在本例中名为<Do>d__0
)包含类型Disposable
的字段,但它本身并不实现{{ 1}}接口。分析器分析编译器生成的代码并没有多大意义(这个IDisposable
类标有<Do>d__0
属性)。幸运的是,代码分析器有一个设置可以避免编译器生成的代码:转到项目属性,&#34;代码分析&#34;选项卡并检查&#34;取消生成的代码&#34;的结果,此警告将消失。
答案 1 :(得分:10)
如果查看IL,您会发现创建了一个类<Do>d__0
来处理异步内容:
// Nested Types
.class nested private auto ansi sealed beforefieldinit '<Do>d__0'
extends [mscorlib]System.Object
implements [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine
{
稍后,此类创建一个Disposable实例:
IL_0074: newobj instance void ConsoleApp1.Disposable::.ctor()
这是触发CA1001的类,因为CA1001检查IL,并且生成的类没有实现IDisposable
。您可以放心地忽略此特定类的CA1001警告。