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,