當類使用異步方法時,似乎Sonar不會計算正確的LCOM4
值。Sonar似乎在處理C#5異步方法時計算無效的LCOM4
我在一個類中有三個async
方法,它們都訪問/操縱類中的相同字段,但LCOM4
表示值爲3,並向我顯示了三種方法。
實際上,在編譯器轉換爲async
方法後,方法不共享相同的字段,這是由於該方法由編譯器轉換爲設置狀態機,而且它是狀態機,在另一種方法中它實際上包含原始方法的代碼。
無論如何,有人可以確認Sonar在處理C#5 async
方法時不能正確計算LCOM4
嗎?有沒有已經存在的解決方案或者是否有計劃?
編輯
這裏是一些代碼示例:
這是一個非常簡單的類的非異步版本:
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;
}
}
一旦通過Sonar,如果我看看LCOM4對於這兩個類的,這裏是我所看到的:
對於LComNonAsync:
方法的凝聚力不足:1
1國家(財產)
System.Void禁用()
System.Void啓用()
而對於LComAsync:
方法的凝聚力不足:2
1 System.Threading.Tasks .Task EnableAsync()
2 System.Threading.Tasks.Task DisableAsync()
我放在async
方法的await
語句,但我相信,即使沒有等待的問題將會出現。這些方法被標記爲async
的唯一事實是觸發了方法的編譯器轉換。如前所述,從IL的角度來看,編譯器轉換之後,公共方法體將被設置狀態機/啓動狀態機所取代,實際的方法原始代碼將被放置在這個狀態機的MoveNext方法。因此,「State」屬性不再在原始公共方法中引用,並觸發LCOM4「違規」。
事實上,這不是我用Sonar和C#5異步/等待獲得的唯一問題。我們已經開始了一個巨大的項目,嚴重依賴於C#5的異步/等待構造,並且必須將我們的項目集成到Sonar中,因爲公司希望我們(幾天前剛剛發現了Sonar,它踢了屁股......儘管事實如此對於某些情況,C#5沒有正確支持......反正)。 我面對的其他問題是靜態代碼分析。我們必須禁用Gendarme,因爲由於C#5的異步方法轉換以及由於任務的使用導致的其他規則,對於某些規則會產生很多完全誤報...所以我們決定依靠FxCop,但是FxCop10是在C#Sonar生態系統中推出的,但它並不考慮.NET Framework 4.5/C#5,所以我們將使用正確支持C#5的FxCop11,但它不能作爲獨立版本使用-yet?它似乎是一個痛苦..從視覺工作室2012採取它,並把它作爲獨立的分析機...無論如何,代碼分析是一個完全不同的關注,並沒有轉達到LCOM4的問題,但這只是爲了共享;)
您能否提供一些示例代碼? – ppapapetrou
@ppapapetrou:對於後期編輯抱歉,但這裏是一些代碼示例! – darkey