1

I have an interface, let's call it IOperation with the only Method

void Operate(TimeSpan time);

One of my implementations is due to hardware restrictions only capable of handling full milliseconds between 4 ms and 1000 ms.

1) Should I throw an exception if someone calls the method with time less than 4 or greater than 1000? If yes, is a NotSupportedException or a ArgumentOutOfRangeException better? Alternatively round up to 4 or down to 1000 if argument does not fit.

2) If time is between 4 and 1000 but the TotalMilliseconds property is fractional, is it OK to just round to full Milliseconds? Or throw an exception?

My favourite way would be to throw in both situations a NotSupportedException, because according to the interface the arguments are not invalid and hence an ArgumentOutOfRangeException does not seem to fit imho.

Furthermore internal rounding seems somehow outvoting the caller without informing him. On the other hand I feel bad about not fully fulfilling the interface contract, how should the caller react to my NotSupportedExceptions, since Interfaces are there to give confidence to the Caller the methods are implemented according to contract

Eugene Podskal
  • 10,270
  • 5
  • 31
  • 53
Creepin
  • 482
  • 4
  • 20

3 Answers3

1
  1. Round up to 4 or down to 1000 if argument does not fit - you shouldn't do it. Your client expects that he will Operate during, say, one minute, but with such approach he will Operate only a second. If you can't live up to the contract, then you should at least be clear about that, otherwise the system may behave unexpectedly.
  2. If time is between 4 and 1000 but the TotalMilliseconds property is fractional, is it OK to just round to full Milliseconds? - it depends. Agree, that most likely loss or addition of, say, half a millisecond time won't be critical for most systems, but on the other hand it theoretically may be used in some hard real time system where every nanosecond matters.
  3. NotSupportedException or ArgumentOutOfRangeException
    • ArgumentOutOfRangeException - assuming that client can't check what is a valid value for that parameter, it will be a violation of Liskov Substitution Principle. But if you provide some additional method like bool IsValid(TimeSpan) then that concern won't apply, because such interface assumes that client checks the parameter with IsValid.
    • NotSupportedException - says that "The exception that is thrown when an invoked method is not supported, or when there is an attempt to read, seek, or write to a stream that does not support the invoked functionality". It seems to be a perfect fit for cases when some specific operation cannot be accomplished due to implementation restriction. Cases like this one. I just recommend to be very specific about the issue(error message) in the exception. You can even use ArgumentOutOfRangeException as NotSupportedException's InnerException to get the best out of both exception types.
Community
  • 1
  • 1
Eugene Podskal
  • 10,270
  • 5
  • 31
  • 53
  • Thanks for your opinions and the helpful links. I decided to throw a `NotSupportedException` in case 1 and case 2 to not domineer the client. I gave it a meaningful message. – Creepin Jan 16 '17 at 12:55
0

You should implement interface segregation principle, based on the hardware system.

0

1) Such rounding up or down could easily lead to unpredictable behaviour. You'd be familiar with this side effect now, you could even write some info about it in method description, but that reduces the code readability, someone who would perhaps use this code in the future may be surprised that argument he provided is completely changed. Try to avoid such side effects anytime it's not a necessity.

2) It depends on the situation, but for most cases such rounding would be fine. Resolution of certain methods involving very short periods of time must be taken into account. Notice that e.g. .NET

DateTime.Now

has system specific resolution and most often it's no less than 10ms.

zavalita
  • 31
  • 1
  • 3