views:

95

answers:

2

I ve just started using Code contract 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));

Note: the original question had a typo and it used to read Contract.Ensures()

I m not sure this is correct, because the contract will be dealing with a IO concern, but nto sure if this is a problem or not.

Basiecally the question is, is there any problem in using Contracts to ensure Io concerns (or external /non unit concerns) Thanks

+2  A: 
  • 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.
Sjoerd
Given that this is an API, I can not assume that the file exists or not, that is the whole point of the question. So that removes the first two bullet points, the third one , I m assuming you are talking about building a path, in that case, I also want to know what is happening. I m sorry but I cant find the point of your answer
Miau
I think the point is that "contracts" in programming are used like `assert`: they document assumptions made by your code and guard against **programmer error** (the code being **used** or **changed** in a way that breaks the assumptions). They are not subsititutes for exceptions, which indicate that something has gone wrong, and would have gone wrong even if the code were perfect, e.g. trying to open a file you don't have permissions for. Your comment indicates ("I can not assume...") that this situation falls into the latter category, so you should use an exception and not a contract.
shambulator
To help decide when to use which, ask "Would it be acceptable if the compiler removed this check in a release build?" Contracts and other `assert`-like things are for *testing and documenting code*. Exceptions are there to handle *unusual circumstances* at runtime.
shambulator
+4  A: 

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.

Hans Passant
+1 This is key; ensures and requires only make sense for things that can be proven to be true. Since files are partially outside the program's control, there is no provability.
Dan Bryant
I just edited the question the ensures was a typo
Miau