C # - When method arguments fail validation, should I throw an exception?

I am building a technical analysis library that I hope others can use in the long run, so I want to make sure that I check the data included in my methods and return something suitable. Right now, if the check fails, I am returning an empty value. Would it be more appropriate to throw an exception? What is the best practice if other developers can use this library? Here is how I am checking now:

/// <summary> /// Calculates the MACD (Moving Average Convergence Divergence) over n periods, where n is the number of elements in the input prices. /// </summary> /// <param name="InputValues">The numbers used for the MACD calculation. Index 0 must be the oldest, with each index afterwards one unit of time forward. There must more values present than what the SlowEMA calls for.</param> /// <param name="FastEMA">Optional: The smaller (faster) EMA line used in MACD. Default value is 12. Must be less than the SlowEMA.</param> /// <param name="SlowEMA">Optional: The larger (slower) EMA line used in MACD. Default value is 26. Must be less than the number of elements in InputValues.</param> /// <param name="SignalEMA">Optional: The EMA of the MACD line. Must be less than the FastEMA.</param> /// <returns>Returns the components of a MACD, which are the MACD line itself, the signal line, and a histogram number.</returns> public MACD CalculateMACD(decimal[] InputValues, decimal FastEMA = 12M, decimal SlowEMA = 26M, decimal SignalEMA = 9M) { MACD result; // validate that we have enough data to work with if (FastEMA >= SlowEMA) { return result; } if (SlowEMA >= InputValues.Count()) { return result; } if (SignalEMA >= FastEMA) { return result; } // Do MACD calculation here return result; } 
+4
source share
5 answers

There are three standard argument exceptions in .Net:

  • ArgumentException
  • ArgumentNullException
  • ArgumentOutOfRangeException

They all have overloads on their constructors so that you can indicate which argument was the problem, and a more detailed message when throwing them.

It would be common practice to use them.

Edit:

In addition to the null (or empty or other) permissible, I still tend to throw an exception, since you do not necessarily know what your library user will work with. If they don't mind zeros, they can always catch the exception and handle it accordingly.

However, if you did not select an exception, you are limited in your ability to tell the consumer of your library what the problem is.

+6
source

This code will not compile as you try to return an unassigned variable. Assuming you are really using MACD result = new MACD(); , answer: it depends. Can you do anything with an initialized object? Then yes, it is normal to return it.

If not, you can return null and check this, or just throw a ArgumentException() .

+1
source

I would consider the fact that an exception should be thrown if your application falls into any erroneous or incorrect state that could cause damage if it continues without processing or without special attention.

If you have too little data to carry out a meaningful analysis, you can decide whether it is correctly received / incorrect / harmful / etc.

It should also be borne in mind that throwing an exception means interrupting the normal execution path of your program and entering an additional path (the path for handling exceptions).

I would inform the user about this situation with some message and let the program end or continue in the usual way, rather than forcibly throw an exception.

0
source

If CalculateMACD used incorrectly because absurd parameters are passed, this can be considered a programming error, and an exception must be thrown. Do not worry about the consequences of throwing an exception in this case, since you need to throw it only when testing the application in the development environment.

However, if problematic parameters can be communicated in a productive environment, you must decide if this is a normal condition. In this case, consider returning the relevant information to the return value (either a special property or returning null ).

If this is an exceptional condition that should not occur, throwing an exception is probably the best way. In this case, make sure that the application will still run smoothly, or at least end with an appropriate and understandable message.

0
source

It is common practice to test your arguments. Libraries exist where general argument checks are performed, so you do not need to repeat these checks. Here is one of them called the Validator Argument , which I wrote and used for my projects.

An example of use would look like this:

 public void AddPerson(string personId, Person personData) { Throw.IfNullOrEmpty(personId, nameof(personId)); Throw.IfNull(personData, nameof(personData)); 

..

 public void Compute(int generation) { Throw.IfNot(() => generation > 100); 

..

  public void Compute(int generation) { Throw.IfOutOfRange(generation, 1, 100, nameof(generation)); 
0
source

All Articles