LCOM4
クラスが非同期メソッドを使用している場合、Sonar はクラスの正しい値を計算しないようです。
クラスに3 つのasync
メソッドがあり、すべてがクラス内の同じフィールドにアクセス/操作しますが、LCOM4
は値 3 を示し、3 つのメソッドを示しています。
実際、メソッドのコンパイラ変換後、メソッドasync
は同じフィールドを共有しません。これは、メソッドが状態マシンをセットアップするためにコンパイラによって変換され、実際にコードを保持する別のメソッドの状態マシンであるためです。オリジナルメソッドの。
とにかく、C#5メソッドLCOM4
を扱うときにSonar が正しく計算しないことを確認できる人はいますか? async
これに対する既存の修正はありますか、それとも計画されていますか?
編集
ここにいくつかのコードサンプルがあります:
非常に単純なクラスの非非同期バージョンを次に示します。
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 Disable()
System.Void Enable()
LComAsync の場合:
メソッドのまとまりの欠如: 2
1 System.Threading.Tasks.Task EnableAsync()
2 System.Threading.Tasks.Task DisableAsync()
await
メソッドにステートメントを入れましたasync
が、await がなくても問題が発生すると確信しています。メソッドにフラグが付けられているという唯一の事実は、メソッドのコンパイラ変換をasync
トリガーしています。async
コンパイラの変換後、IL の観点から、前に述べたように、パブリック メソッド本体は、ステート マシンの設定/ステート マシンの起動に置き換えられ、メソッドの実際の元のコードは、このステート マシンの MoveNext メソッド。したがって、「状態」プロパティは元のパブリック メソッドで参照されなくなり、LCOM4 の「違反」がトリガーされます。
実際、Sonar と C#5 の async/await で発生した問題はこれだけではありません。私たちは C#5 の async/await 構造に大きく依存する巨大なプロジェクトを開始しましたが、会社が私たちに望んでいたため、プロジェクトを Sonar に統合する必要がありました (数日前に Sonar を発見したばかりで、お尻を蹴ります ... 事実にもかかわらず特定の事柄については、C#5 が正しくサポートされていません ...とにかく)。私が直面している他の問題は、静的コード分析に関するものです。Gendarme を無効にする必要があったのは、C#5 による非同期メソッド変換が原因で、特定のルールで多くの完全な誤検知が発生するためであり、タスクの使用が原因でその他のルールが原因でした...そのため、FxCop に依存することにしましたが、 FxCop10 は C# Sonar エコシステムで提供されていますが、.NET Framework 4.5 / C#5 も考慮されていません。