English 中文(简体)
Is it ok for different implementing classes to throw different exception types?
原标题:

If i have an interface, which i add comments to to identify that a specific exception will be thrown, is it ok for implementing classes to throw different exceptions?

A (bad) example is:

public interface IWidgetWorker {
    /// <summary>
    /// Do the work required for the specified work id.
    /// </summary>
    /// <param name="workId">The id of the piece of work to do</param>
    /// <exception cref="ArgumentException">Thrown if workId is empty</exception>
    public void DoWork(Guid workId);
}

public class DatabaseWidgetWorker : IWidgetWorker {
    public void DoWork(Guid workId) { 
        // throw some database related exception
    }
}

public class WebWidgetWorker : IWidgetWorker {
    public void DoWork(Guid workId) {
        // throw some web related exception
    }
}

Maybe i add a WidgetWorkerException class? Where do i document what the specific exceptions that the implementing classes might throw?

最佳回答

Part of an interface design often documents the expected exceptions. These exceptions are logical at the time of the creation of the interface, for example an InvalidOperationException for when a method is called and the object is in the wrong state or an ArgumentOutOfRangeException when an improper parameter is passed.

However, interfaces can be implemented in any number of ways. It s entirely possible for an implementation to look at a file system or call to a database, introducing a range of exceptions that were not foreseeable when the interface was defined.

The only reason you would want to know that a method throws a specific exception is to be able to handle that condition differently from general exception handling. When you make a call through an interface, you are coding against the interface and not the implementation. You cannot know how the implementation works and therefore cannot handle exceptions in any specific manner. You must fall back to more general exception handling.

The rule of thumb should be to document exceptions which are sensible given the exposed interface, but that you should expect an implementation to throw exceptions beyond these. Robust code will have a mechanism for handling these unknown exceptions in a generic fashion.

问题回答

Implementing classes should only throw the exceptions specified in the interface. If the interface doesn t provide for any possibility to report the error, either the interface is badly designed or the implementors should suck it up, because the interface user really doesn t care.

This is probably subjective. My feeling is that the implementing classes should throw whatever exceptions that is natural to throw at the time. The interface does not declare which exceptions are allowed and which aren t. The compiler does not look at your comments, and a class can throw other exceptions and still be a valid implementation of your interface.

If, for some reason you need those exceptions to be of a single type, you could catch them and rethrow them with the original as inner exception wherever IWidgetWorker.DoWork is called.

The situation where workId is empty, could be handled before the call goes to the implementation, so there is no reason why different implementations should handle the same checking and throwing of ArgumentException.

It might be different in other programming environments. I think that possible exceptions must be declared in some languages, but not here.

The documentation of your interface could say something about how various exceptions are interpreted and what the consuming code will do. Maybe the consuming code will try again after some time interval if the exception is such and such, but will terminate report error in other cases.





相关问题
Manually implementing high performance algorithms in .NET

As a learning experience I recently tried implementing Quicksort with 3 way partitioning in C#. Apart from needing to add an extra range check on the left/right variables before the recursive call, ...

Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

How do I compare two decimals to 10 decimal places?

I m using decimal type (.net), and I want to see if two numbers are equal. But I only want to be accurate to 10 decimal places. For example take these three numbers. I want them all to be equal. 0....

Exception practices when creating a SynchronizationContext?

I m creating an STA version of the SynchronizationContext for use in Windows Workflow 4.0. I m wondering what to do about exceptions when Post-ing callbacks. The SynchronizationContext can be used ...

Show running instance in single instance application

I am building an application with C#. I managed to turn this into a single instance application by checking if the same process is already running. Process[] pname = Process.GetProcessesByName("...

How to combine DataTrigger and EventTrigger?

NOTE I have asked the related question (with an accepted answer): How to combine DataTrigger and Trigger? I think I need to combine an EventTrigger and a DataTrigger to achieve what I m after: when ...

热门标签