0

LCOM4当类使用异步方法时,Sonar 似乎没有计算类的正确值。

async在一个类中有三个方法,所有方法都访问/操作类中的相同字段,但LCOM4指示值为 3,并向我显示这三个方法。

实际上,在方法的编译器转换之后,async方法不共享相同的字段,因为编译器将方法转换为设置状态机,它是状态机,在另一个实际保存代码的方法中的原始方法。

LCOM4无论如何,任何人都可以确认 Sonar在处理 C#5async方法时没有正确计算吗?是否有任何现有的解决方案或是否有计划?

编辑

这里有一些代码示例:

这是一个非常简单的类的非异步版本:

public class LComNonAsync
{
    public bool State { get; private set; }

    public void Enable()
    {
        this.State = true;
    }

    public void Disable()
    {
        this.State = false;
    }
}

这是异步版本:

public class LComAsync
{
    public bool State { get; private set; }

    public async Task EnableAsync()
    {
        await Task.Yield();
        this.State = true;
    }

    public async Task DisableAsync()
    {
        await Task.Yield();
        this.State = false;
    }
}

一旦通过声纳,如果我看一下这两个类的 LCOM4,我可以看到以下内容:

对于LComNonAsync

方法缺乏凝聚力:1

1 个州(财产)

System.Void 禁用()

System.Void 启用()

对于LComAsync

方法缺乏凝聚力:2

1 System.Threading.Tasks.Task EnableAsync()

2 System.Threading.Tasks.Task DisableAsync()

await在方法中添加了一个声明,async但我确信即使没有等待,问题也会存在。async方法被标记为触发async编译器转换方法的唯一事实。编译器改造后,从IL的角度来看,正如我之前所说,公共方法体将被设置状态机/启动状态机所取代,方法的实际原始代码将放在此状态机的 MoveNext 方法。因此,原来的公共方法中不再引用“State”属性,触发LCOM4“违规”。

事实上,这不是我在使用 Sonar 和 C#5 async/await 时遇到的唯一问题。我们已经开始了一个严重依赖 C#5 的 async/await 结构的大型项目,并且不得不将我们的项目集成到 Sonar 中,因为公司希望我们这样做(几天前刚刚发现了 Sonar,它踢屁股......尽管事实上对于某些事情,C#5 没有得到正确的支持......无论如何)。我面临的其他问题是静态代码分析。我们不得不禁用宪兵,因为它对某些规则产生了很多完全误报,由于 C#5 的异步方法转换,以及由于使用任务的其他规则......所以我们决定依赖 FxCop,但是FxCop10 在 C# Sonar 生态系统中提供,但也不考虑 .NET Framework 4.5 / C#5,

4

1 回答 1

0

在撰写本文时,由于缺乏答案和我的测试,我认为 Sonar 在计算 LCOM4 时无法与 C#5 async/await 结构一起正常工作。

于 2013-08-13T17:49:07.430 回答