C# – Documenting Interfaces and their implementation

cdocumentationdocumentation-generationinterfacesandcastle

I'm decorating my C# code with comments so I can produce HTML help files.

I often declare and document interfaces. But classes implementing those interfaces can throw specific exceptions depending on the implementation.

Sometimes, the client is only aware of the interfaces he's using. Should I document my interfaces by adding the possible exceptions that could be thrown by its implementors?

Should I create/document custom exceptions so that interfaces implementors throw these instead of those of the framework?

I hope this is clear!

Thanks

EDIT jan 4th 2010: I decided to write a blog post about this and custom exceptions in .NET at http://blog.mikecouturier.com/2010/01/creating-custom-exceptions-in-net-right.html

Best Answer

I am not sure I fully understood your question (and I'm a Java, not C# developer), but it seems you are asking about what is essentially an issue of polymorphism: if somebody uses a method on an interface that is declared to throw X and Y, what happens if an implementation throws Z?

One thing to follow is the principle of conformance, that essentially says that a subtype should conform to the behavior of the supertype. That is, if you are documenting that your method in the interface can only throw exceptions of one type (e.g., null pointer exceptions), then your contract with callers is that this is the only thing they should watch for. If you throw something else, you could be surprising them.

Documenting things about a specific subtype in the supertype not a good idea since it creates needless coupling. I would be more concerned about the fact that an implementation may behave differently than the declaration since that might suggest the declaration is not fleshed out enough.

Try to think what are all the types of exceptions that your method could throw. Create supertypes for them, and then explicitly declare in your interface method (e.g., this method can throw some "calculation exception"). Then, in your implementation, throw a calculation exception with more details, or throw some subtype of the calculation exception that is specific to the implementation, you would still conform.