2011-09-05 43 views
2

如果我能做魔法,我會想出一個C#代碼分析工具;我們稱之爲XYZ。下面是一些代碼的例子,你可以輸入給XYZ分析面向對象代碼的想法

public class MyClass 
{ 
    private int myInt; 

    [Functional] 
    public int GetDoubleOfMyInt() 
    { 
     return 2*myInt; 
    } 

    [SideEffect: myInt] 
    public void IncrementMyInt() 
    { 
     myInt++; 
    } 
} 

通知,這兩種方法的標籤。 XYZ將驗證GetDoubleOfMyInt()確實是純粹的功能(就其僅計算整數而言),並且IncrementMyInt具有將值分配給myInt的副作用。如果換了兩個標籤XYZ會發出兩個錯誤。

我的問題: 1.是否確實存在一些倒鉤XYZ? 2.如果你被要求實施它,你會從哪裏開始?

+1

您是否聽說過[代碼合同](http://msdn.microsoft.com/zh-cn/devlabs/dd491992)? –

+1

'Functional'不是特別描述性的。考慮「純」或「無副作用」之類的東西。還要注意的是,有一些數據結構對外部是純粹的功能,但是在引擎蓋下大量使用可變性 - 這些*的正確性會更有用,但也更難。 – delnan

+1

發表評論是因爲它不是一個真正的答案,但如果你有時間和傾向,你可以看看Ada是如何工作的,也許會吸取一些啓發;它將過程(可能會修改它們的輸入)與函數(可能不會)分開,並且有幾個編譯器編譯指示,如Pure pragma,表示代碼沒有副作用。 – Uffe

回答

8

代碼合同本質上是做你在問什麼。 (http://msdn.microsoft.com/en-us/devlabs/dd491992

代碼合同允許您使用允許編譯器和IDE靜態分析代碼的屬性和調用來修飾代碼。您可以在System.Diagnostics.Contracts命名空間中找到代碼合同,但要充分利用完整的靜態類型檢查,您至少需要Visual Studio的Premium版SKU(我認爲)。

一個簡單的例子,你Functional屬性本質上是一樣的Pure

[Pure] 
public void GetMessage() { return _message; } 

告訴分析儀,該方法不作任何狀態變化。您也可以對您的方法進行事先和事後條件,例如:

public void WriteMessage(string message) 
{ 
    Contract.Requires(message != null); 
} 

代碼合同中有很多深度,值得一讀。

2

static analysis tool NDepend幾乎可以描述您正在描述的內容。看看這個默認碼查詢規則,找到方法,但如(因爲貼上了 PureAttribute)和不是了:你可以使用自己的

// <Name>Regression on pure methods</Name> 
WARN IF Count > 0 IN SELECT METHODS WHERE 
    HasAttribute "OPTIONAL:NDepend.CQL.PureAttribute" AND 
    (ChangesObjectState OR ChangesTypeState) AND 
    NbLinesOfCode > 0 

// A method is pure if its execution doesn’t change 
// the value of any instance or static field. 
// Pure methods naturally simplify code by limiting 
// side-effects. 
// See some explanations on immutability - purity and 
// how NDepend supports it here: 
// http://codebetter.com/blogs/patricksmacchia/archive/2008/01/13/immutable-types-understand-them-and-use-them.aspx 

// NDepend.CQL.PureAttribute is defined in the 
// redistributable assembly $NDependInstallDir$\Lib\NDepend.CQL.dll 
// You can define your own attribute to tag 'pure' methods. 

通知 PureAttribute而不是規則中默認指定的那個,只需指定您的屬性 namespace.nameAttribute

注意,CQL (Code Query Language)子句 ChangesObjectState ChangesTypeState返回true該分配實例(對象)方法靜態(類型)字段。