Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code contracts usage patterns when dealing with Files

I've just started using Code Contracts with .NET and I had a guard clause like this

if (!file.Exists(path)) throw FileNotFoundException();

and replaced it with

Contract.Requires(File.Exists(path));

I'm not sure this is correct, because the contract will be dealing with an I/O concern, but not sure if this is a problem or not.

Basically the question is: Is there any problem in using Contracts to ensure I/O concerns (or external/non-unit concerns)?

like image 472
roundcrisis Avatar asked Jan 21 '23 19:01

roundcrisis


2 Answers

Whether a file exists is normally a pre-condition, you'd use Contract.Requires(). Enabling contract verification is optional and not normally turned on in the Release build. Which makes your test disappear.

Frankly, you shouldn't write code like this. Any attempt to use the file will generate an exception, it will be more informative than your version. It includes the name of the file that could not be found. More to the point, File.Exists() is unreliable on a multi-tasking operating system. The thread could be pre-empted right after the Exists() call and another thread in another process could delete the file. And you'll have a heisenbug on your hands: you'll get a FileNotFound exception, even though you tested that it existed.

My call: just delete the statement. It causes more problems than it solves.

like image 74
Hans Passant Avatar answered Feb 05 '23 08:02

Hans Passant


  • If you are unsure whether the file exists, don't use exceptions.
  • If the file should exist, but may not in some exceptional case, use exceptions.
  • If you are sure that it is a programming error that the file does not exist, use Contract.Ensures.
like image 26
Sjoerd Avatar answered Feb 05 '23 06:02

Sjoerd