2012-01-11 14 views
1

在傳統的代碼庫中,由於許多技術原因,我們正在將以前基類類型的參數替換爲接口類型。例如:是否有任何代碼分析工具在比較特定類型時檢測==運算符?

public interface IDomainObject { int Id { get; } } 

public abstract class BaseDomainObject : IDomainObject 
{ 
    public int Id { get; protected set; } 
    public override bool Equals(object obj) 
    { 
     var domainObj = obj as BaseDomainObject; 
     return domainObj != null && Id.Equals(domainObj.Id); 
    } 
    public static bool operator ==(BaseDomainObject x, BaseDomainObject y) 
    { 
     return !ReferenceEquals(x, null) && !ReferenceEquals(y, null) && x.Equals(y); 
    } 
    public static bool operator !=(BaseDomainObject x, BaseDomainObject y) 
    { 
     return !(x == y); 
    } 
} 

public class MyDomainObject : BaseDomainObject 
{ 
    public MyDomainObject(int id) { Id = id; } 
    ... 
} 

所以在代碼中,我們以前將有型BaseDomainObject的變量無處不在,我們現在有型IDomainObject之一。但是,我們遇到了'=='運算符的問題 - 它不適用於接口。對於所有接口類型,'=='運算符只需回落到ReferenceEquals()

下面的代碼演示了此問題:

// Old style 
    BaseDomainObject baseobj1A = new MyDomainObject(1); 
    BaseDomainObject baseobj1B = new MyDomainObject(1); 
    BaseDomainObject baseobj2 = new MyDomainObject(2); 

    Assert.IsTrue(baseobj1A != baseobj2); 
    Assert.IsTrue(baseobj1A == baseobj1B); // Succeeds 

    // New style 
    IDomainObject iobj1A = new MyDomainObject(1); 
    IDomainObject iobj1B = new MyDomainObject(1); 
    IDomainObject iobj2 = new MyDomainObject(2); 

    Assert.IsTrue(iobj1A != iobj2); 
    Assert.IsTrue(iobj1A == iobj1B); // Fails 

再回到使用基類不是一個選項 - 我們的接口是通用的共變體(類似於IDomainObject <出T>),其對於我們需要的多態行爲是必需的。理想情況下,我們只需用.Equals()替換所有'=='。但是,我們的代碼庫非常龐大,而查找所有我們關心的'=='運算符將是一項艱鉅的任務。

一個想法是,我們可以編寫一個FxCop規則來標記在'=='比較中使用的某個接口類型的變量(即,IDomainObject)的所有變量。但是這不起作用--FxCop不支持這一點。另一個想法是編寫我們自己的代碼分析工具,只是檢查這種情況,但這會很耗時。

所以問題是,是否已經有一些代碼分析工具在那裏,我們可以用它來找到這些'=='發生?

+0

您可以使用jetbrains.com的R#工具來查找所有類型的用法。它支持插件,您可以添加所需的功能。 – 2012-01-11 16:39:15

+0

不,找到用法並沒有找到它們。 – afeygin 2012-01-11 16:50:17

+0

你爲什麼說FxCop不支持這個?您是否真的嘗試創建一個自定義的FxCop規則來查找針對您的目標接口實例的不適當的相等性驗證? – 2012-01-11 17:18:19

回答

0

如果Visual Studio的「查找所有引用」無法找到==的特定實現的所有用法,我很確定Resharper的「查找用法」能夠毫無問題地找到它們。

1

您可以使用自定義搜索模式與ReSharper做這樣的事情。

你也可以考慮做這個「老式的方式」。更改所有引用,然後修復編譯錯誤。

相關問題