Идея для анализа объектно-ориентированного кода - PullRequest
2 голосов
/ 05 сентября 2011

Если бы я мог творить чудеса, я бы вызвал инструмент анализа кода на 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. Если бы вас попросили осуществить это, с чего бы вы начали?

Ответы [ 2 ]

8 голосов
/ 05 сентября 2011

Code Contracts по сути делает то, что вы просите.(http://msdn.microsoft.com/en-us/devlabs/dd491992)

Контракты кода позволяют вам украшать ваш код атрибутами и вызовами, которые позволяют компилятору и IDE статически анализировать ваш код. Контракты кода можно найти в пространстве имен System.Diagnostics.Contracts, но вы можете воспользоватьсяДля полной статической проверки типов вам нужен как минимум Premium SKU Visual Studio (я думаю).

Быстрый пример, ваш атрибут Functional по сути такой же, как Pure:

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

Что говорит анализатору, что метод не вносит изменений в состояние. Вы также можете выполнять предварительные и последующие условия для своих методов, например:

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

В Code Contracts много глубины,и стоит хорошего чтения.

2 голосов
/ 06 сентября 2011

Инструмент статического анализа NDepend в значительной степени выполняет то, что вы описываете.Взгляните на это правило запроса кода по умолчанию, которое находит методы, которые pure (потому что помечены PureAttribute ) и которые больше не pure :

// <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 (язык запросов кода) предложения ChangesObjectState и ChangesTypeState возвращает true для методов, которые присваивают экземпляр (объект) или статическое (тип) поле.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...