Checking function arguments?

I regularly check function arguments:

public static void Function(int i, string s) { Debug.Assert(i > 0); Debug.Assert(s != null); Debug.Assert(s.length > 0); } 

Of course, the checks are "valid" in the context of the function.

Is this common industry practice? What is the usual practice of validating arguments?

+4
source share
9 answers

The accepted practice is as follows if the values ​​are invalid or later throw an exception:

 if( i < 0 ) throw new ArgumentOutOfRangeException("i", "parameter i must be greater than 0"); if( string.IsNullOrEmpty(s) ) throw new ArgumentNullException("s","the paramater s needs to be set ..."); 

Thus, the list of exceptions to the main arguments is as follows:

  ArgumentException
 ArgumentNullException
 ArgumentOutOfRangeException
+10
source

What you wrote is prerequisites and an important element in Design by Contract . Google (or "StackOverflow" :) for this period, and you will find quite a lot of good information about it, as well as some bad information. Note that the method also includes postconditions and the concept of a class invariant .

Keep clear that statements are a valid mechanism.

Of course, they usually ( not always ) are not checked in release mode, so this means that you need to check your code before releasing it.

If statements are left included and the statement is violated, standard behavior in some languages ​​that use statements (in particular, in the Eiffel) is an exception to the exclusion of the statement.

Statements that have not been noted are not a convenient or appropriate mechanism if you publish a library of codes, as well as a (obviously) way to verify direct, possibly incorrect, input. If you have “possibly incorrect input”, you need to develop an input validation level as part of your program’s normal behavior; but you can still freely use assertions in internal modules.


Other languages, such as Java, have a more tradition of explicitly checking arguments and throwing exceptions if they are mistaken , mainly because these languages ​​do not have a strong “statement” or “design” by contract.

(This may seem strange to some, but I find the differences in tradition respectable and not necessarily evil).

See also this related question .

+5
source

You should not use statements to validate data in a real application. I understand that statements are intended to verify the correct use of a function. Or that the function returns the correct value. Ie the value that you get is what you expected. They are used a lot in test environments. They are designed to shut down during system deployment because they are slow. If you want to handle invalid cases, you must do it explicitly, like the poster mentioned above.

+3
source

Any code that is called over the network or through interprocess communication must have a parameter check, because otherwise it is a security vulnerability, but you should throw an exception. Debug.Assert simply will not do as it only checks for debug builds.

Any code that other people on your team will use should also have parameter checks, only because it will help them find out about it when they give you an invalid value, again this time you should throw exceptions, because you can add A good description of the exception with an explanation of what they did wrong and how to fix it.

Debug.Assert in your function is just to help you debug, this is a good first line of defense, but it is not a “real” check.

+2
source

For public functions, especially API calls, you should throw exceptions. Consumers would probably be happy to find out that there is an error in their code, and an exception is a guaranteed way to do this.

For internal or private functions, Debug.Assert is excellent (but not required, IMO). You will not accept unknown parameters, and your tests should catch any invalid values ​​for the expected result. But sometimes Debug.Assert will allow you to reset or prevent an error that is much faster.

For public functions that are not API calls, or internal methods that may be called by other people, you can go anyway. I usually prefer exceptions to public methods and (usually) let internal methods dispense with exceptions. If the internal method is particularly prone to misuse, then the exception is justified.

As long as you want to validate the arguments, you do not need 4 levels of validation that you must synchronize (and pay a fine for the fine). So, check on the external interface and just hope that you and your employees can call functions accordingly and / or fix the error that will inevitably result.

+2
source

In most cases, I do not use Debug.Assert, I would do something like this.

 public static void Function(int i, string s) { if (i > 0 || !String.IsNullOrEmpty(s)) Throw New ArgumentException("blah blah"); } 

ATTENTION: This is an air code, I have not tested it.

+1
source

You must use Assert to verify software assumptions; those. for a situation where

  • you are the only one calling this method
  • it must be an impossible condition to enter

Assert statements allow you to double check that an impossible state is never reached. Use this to prevent you from feeling comfortable without checking otherwise.

In situations where bad arguments are assigned to functions, but you can see that it is not impossible to get these values ​​(for example, when someone else could have called this code), you should throw exceptions (a la @Nathan W and @Robert Paulson ) or unsuccessfully elegant (a la @Srdjan Pejic ).

+1
source

I try not to use Debug.Assert, rather I write guards. If the function parameter does not match the expected value, I exit the function. Like this:

 public static void Function(int i, string s) { if(i <= 0) { /*exit and warn calling code */ } } 

I find that this reduces the amount of controversy that should occur.

-1
source

I will not talk with industry standards, but you could combine the two bottom statements in one line:

 Debug.Assert(!String.IsNullOrEmpty(s)); 
-2
source

All Articles