2013-06-11 52 views
0

當類使用異步方法時,似乎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的問題,但這只是爲了共享;)

+0

您能否提供一些示例代碼? – ppapapetrou

+0

@ppapapetrou:對於後期編輯抱歉,但這裏是一些代碼示例! – darkey

回答

0

在寫這篇文章時,由於缺乏答案和我的測試,我認爲Sonar在計算LC時不能正確使用C#5異步/等待結構OM4。