Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code contracts .net - alternatives

Recently, I started to use Code contracts for .net. The idea of code contracts itself is great in my opinion, but the implementation is very unpleasant.

The main reasons I don't like it are:

  • I can use only methods like Contract.Require() inside my procedures. ContractAbbreviators have so many restrictions (like, I cannot put them in a separate assembly and I cannot use parameters) that it makes them less usable. There are no attributes, and no extension methods, so my code becomes very verbose. For example, if I just want to check that my return value of type Dictionary<string, string>is not null, I need to add a monster such as Contract.Ensure(Contract.Result<Dictionary<string, string>> != null). It's not even readable.
  • The static analyzer makes so many false alarms that I spend more time shutting it up than fixing actual problems.
  • It is extremely slow. Even though it has some cache, it takes a few minutes to analyze even a small project, and that makes it useless for incremental fixing. It just takes too long.
  • There are bugs in ccrewriter—it cannot chew half of assemblies, and it cannot survive .net 4.0 assemblies in the .net 4.5 runtime.
  • There is runtime/static checker dualism. When I had just started I thought it was as simple as Debug.Assert—you just add them everywhere you feel you need. But it turns out that I need to prove everything to the static checker, which is advanced, for sure, but the checker is stupid sometimes and can't resolve many obvious code constructions (like while). And there's no instrument to just say to the analyzer "I know what I'm doing, just ignore this contract violation".
  • You cannot relate conditions. For example, there is no way to explain to the static analyzer that if I check string.NotNullOrEmpty this includes string != null. Or if I have my own big procedure checking a file path, I cannot explain to the analyzer that it's for sure not null and not empty. The ContractAbbreviator attributes help a little bit, but all this verbosity goes there and it still looks dirty and stupid.
  • Code contracts is being developed very slowly, and even though it is open source now, as far as I know the code base is in a bad state.

Is there any advanced alternative to Code Contracts which has fewer flaws?

like image 668
Alex Butenko Avatar asked Dec 09 '22 00:12

Alex Butenko


1 Answers

I don't know of any alternatives, but I perhaps I can address a few of your issues. I work in a team that uses contracts in all our code (~1000 modules) and run static analysis on every checkin as well as in VS.

  • Code ugliness. We have separate interfaces for (almost) everything, along with abstract classes implementing those, joined by ContractClass and ContractClassFor attributes. The contracts are in the abstract ContractClassFor-classes which makes the actual implementation code almost free from code contracts.

  • Static analyzer slowness is often due to not enough contracts, which forces the analyzer to do more work to find out if contracts can be broken.

  • Static checker false Alarms. I have had a few, but not to an extent where it has become a problem. Again, if you have too few contracts, the static checker might not be able to complete the analysis in time.

  • Static analyzer slowness can be debugged with these MSBuild options, which will show which methods take the most time to analyze.

    msbuild myproject.sln /p:CodeContractsExtraAnalysisOptions="-show progress -stats=!! -stats slowMethods"

  • If you're certain that some condition always holds, then you can use Contract.Assume(condition) to instruct the static checker to assume that this is the case. Eg.

    Contract.Assume(mystring != null && mystring != "") or maybe just Contract.Assume(!string.IsNullOrEmpty(mystring))

  • Regarding the use of Debug.Assert, I think it's a huge advantage to have the static checking instead of just making my application crash at the customers site. This way, I can remove the risk of having the application crash before I release the product. Maybe I misunderstand you, but I really don't think your comparison makes sense.

like image 129
Kenned Avatar answered Jan 20 '23 10:01

Kenned