Question

I've been reading articles on how to program in a functional (i.e F#) style in C#, for example, foregoing loops for recursion and always returning a copy of a value/object instead of returning the same variable with a new state.

For example, what sort of code inspection things should I watch out for? Is there any way to tell if a method on a BCL class causes a mutation?

Was it helpful?

Solution

Here are two things that would help you find variables and fields whose values are getting changed. Mutability is more complex than this, of course (for example these won't find calls to add to collections) but depending on what you're looking for, they may be helpful.

  1. Make all of your fields readonly; then they can only be set from the constructor, and not changed thereafter.

  2. Pick up a copy of ReSharper. It expands on Visual Studio's syntax highlighting, and has an option to set up custom highlighting for mutable local variables. This will let you see at a glance whether locals are being modified.

OTHER TIPS

The tool NDepend can tell you where you have side effect. It can also ensure automatically that a class is immutable (i.e no side effect on its object instances) or a method is pure (i.e no side effects during the execution of the method. Disclaimer: I am one of the developers of the tool.

In short, trick is to define an attribute, such as, MyNamespace.ImmutableAttribute and to tag classes that you wish to be immutable.

[Immutable]class MyImmutableClass {...}

If the class is not immutable, or more likely, if one day a developer modifies it and breaks its immutability, then the following Code Rule over LINQ Query (CQLinq) will suddenly warn:

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

On a side note, I wrote an article on immutability/purity/side-effects and NDepend usage: Immutable Types: Understand Them And Use Them

Unfortunately there's no easy way to do that in C# currently. If you're lucky the documentation will tell you, but generally that is not the case.

Inspecting the code with Reflector (assuming we're talking managed code) can reveal if the current implementation has any side effects, but since this is an implementation detail there's no guarantee that it will not change in the future, so basically you will have to repeat the verification every time you update the code in question.

Tools such as NDepend can help you find out dependencies between types - i.e. where you have too look for side effects.

For your own types, you can implement immutability, by making sure instances never leak references to internals. Make sure to copy the contents of reference type instances used to instantiate the objects as other may otherwise keep references to internal state.

Without testing the method, you won't be able to tell if it has any side effects. It would be handy if the documentation mentioned any side effects of a method or function but unfortunately it doesn't.

Keep in mind that you will have to do some extensive testing to be certain that no side effects can occur. If you want to you can always disassemble the assembly and read the code for side effects.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top