2009-04-30 4 views
3

Я читал статьи о том, как программировать в функциональном стиле (например, F #) в C#, например, предшествующие циклы для рекурсии и всегда возвращать копию значения/объекта вместо того, чтобы возвращать одну и ту же переменную с новым состоянием ,Как обнаружить мутацию в функции C#?

Например, какие проверки кода я должен соблюдать? Есть ли способ узнать, вызывает ли метод класса BCL мутацию?

+9

Если ваш код начинает идти с выраженной лимпиткой, он развивает lisp и начинает называть вас «mashter», вы знаете, что он мутировал. :) (извинения, я не удержался) –

+0

Это сложнее, чем вы думаете. Но прежде всего, если какие-либо нелокальные переменные в функции появляются в левой части присваивания или изменены любыми вызовами функций, выполненными внутри этой конкретной функции, тогда у вас есть возможная мутация. На самом деле это довольно сложная проблема, в частности, из-за таких вещей, как отражение и т. Д. – BobbyShaftoe

ответ

2

Вот две вещи, которые помогут вам найти переменные и поля, значения которых изменяются. Разумеется, взаимная совместимость сложнее, чем это (например, они не найдут вызовов для добавления в коллекцию), но в зависимости от того, что вы ищете, они могут быть полезными.

  1. Внесите все свои поля только для чтения; то они могут быть установлены только из конструктора и не изменены после этого.

  2. Поднять копию ReSharper. Он расширяет подсветку синтаксиса Visual Studio и имеет возможность настраивать пользовательскую подсветку для mutable local variables. Это позволит вам сразу увидеть, изменяются ли местные жители.

+0

Для ссылочного типа readonly сделайте ссылку только для чтения, а не экземпляр, на который он указывает. Таким образом, сам экземпляр может быть изменен. –

+0

Правда, вот почему я сказал, что это не полное решение и не найдет таких вещей, как «Добавить вызовы в коллекциях». –

0

Без тестирования метода вы не сможете определить, есть ли у него какие-либо побочные эффекты. Было бы удобно, если бы в документации упоминались какие-либо побочные эффекты метода или функции, но, к сожалению, это не так.

Имейте в виду, что вам нужно будет провести тщательное тестирование, чтобы быть уверенным, что побочных эффектов не возникает. Если вы хотите, вы всегда можете разобрать сборку и прочитать код для побочных эффектов.

1

К сожалению, в C# в настоящее время нет простого способа сделать это. Если вам повезет, документация вам скажет, но в целом это не так.

Проверка коды с отражателем (предполагая, что мы говорим управляемый код) может показать, если ток реализации имеет какие-либо побочные эффекты, но так как это деталь реализации нет никакой гарантии, что она не изменится в будущем, поэтому в основном вам придется повторять проверку каждый раз, когда вы обновляете данный код.

Такие инструменты, как NDepend, могут помочь вам найти зависимости между типами - например, если вы тоже ищете побочные эффекты.

Для ваших собственных типов вы можете реализовать неизменность, убедившись, что экземпляры никогда не течет ссылки на внутренние элементы. Обязательно скопируйте содержимое экземпляров ссылочного типа, используемых для создания экземпляров объектов, так как другие могут иначе ссылаться на внутреннее состояние.

4

Инструмент NDepend может сообщать вам, у кого есть побочный эффект. Он также может автоматически гарантировать, что класс является неизменным (то есть без побочного эффекта на его экземплярах объекта), или метод является чистым (т.е. без побочных эффектов во время выполнения метода. Отказ от ответственности: Я являюсь одним из разработчиков этого инструмента.

Короче говоря, трюк заключается в том, чтобы определить атрибут, например MyNamespace.ImmutableAttribute , и пометить классы, которые вы хотите быть неизменными.

[Immutable]class MyImmutableClass {...} 

Если класс не является неизменным, или, скорее всего, если один день разработчик изменяет его и ломает его неизменность, то следующее Code Rule over LINQ Query (CQLinq) внезапно предупреждают:

warnif count > 0 
from t in Application.Types 
where !t.IsImmutable && t.HasAttribute("MyNamespace.ImmutableAttribute") 
select t 

На стороне записки, Я написал статью о неизменности/чистоте/побочных эффектах и ​​использовании NDepend: Immutable Types: Understand Them And Use Them

Смежные вопросы