CA1001在异步方法上实现IDisposable

问题描述 投票:31回答:2

考虑以下代码:

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。<Do> d__0因为它创建了以下IDisposable类型的成员:'Disposable'。

为什么我收到此消息?一次性类正确处理,我不存储在任何地方。

此外,这似乎适用于分析仪:

public class Test
{
    public void Do()
    {
        using (var disposable = new Disposable())
        {
            disposable.Do();
        }
    }
}
c# .net visual-studio async-await code-analysis
2个回答
28
投票

这是因为编译器从您的异步方法生成状态机,并且该状态机类(在本例中名为<Do>d__0)包含Disposable类型的字段,但本身并不实现IDisposable接口。分析器分析编译器生成的代码没有多大意义(这个<Do>d__0类标有CompilerGenerated属性)。幸运的是,代码分析器有一个设置可以避免编译器生成的代码:转到项目属性,“代码分析”选项卡并选中“从生成的代码中抑制结果”,此警告将消失。


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警告。

© www.soinside.com 2019 - 2024. All rights reserved.