C# .NET Null-checking params array
Do you need to null check a "params" array?
The C# programming language allows for the creation of methods that take an arbitrary number of arguments via the params
keyword. Although I have used that feature many times, and null-checked the array every time, I have never really stopped to think about whether the array is or is not null,until now. Is it necessary to null-check the params
array -- YES.
Consider the following method stub that fairly typical of something that uses the params
keyword.
public void MyMethodA (
params string[] messages)
{
// Is it necessary to null-check the 'params' array
if ( (null == messages) || (messages.Length < 1) )
{
return;
}
foreach (var msg in messages)
{
// Do something
}
}
If it is not necessary to null-check, it could be simplified to something like this because it is safe to foreach
over a non-null, empty (Length == 0) array. It will just skip over if the length is zero!
public void MyMethodB (
params string[] messages)
{
foreach (var msg in messages)
{
// Do something
}
}
If you call the method without specifying any arguments, the compiler will automatically create and pass in an empty array as the params
array. Therefore, the following two are exactly the same.
MyMethodA();
MyMethodA(new string[0]);
Recall that the C# language, for the params
array, allows one to specify an actual array in lieu of the arbitrary number of parameters. Therefore, the following two lines are exactly the same,
MyMethod("ABC", "DEF", "EHI");
MyMethod( new string[]{"ABC", "DEF", "EHI"} );
So far, so good. In all four of the examples of calling MyMethodA
above, an array was always passed in, not null
, so there has not yet been a reason to null-check. But, that is not the end of the story.
There is actually an interesting ambiguity. What happens if null
is passed in. Does it look like a an array of size one where the first element is null, or does it look like a null array?
// Is this call...
MyMethdodA(null);
// ...the same as this call...
MyMethodA(new string[] { null } );
// ...or more like this call?
string[] p = null;
MyMethodA(p);
Well, the answer is the later. If you pass null in as the first and only value of the params argument, the compiler passes a null array into the method. Therefore, MyMethodA
is safe since it has the null-check, but MyMethodB
would throw a NullReferenceException
.
If you think about it, that is actually the behavior one should expect. After all, the array can be of any type, which means it could also be of a value type such as int
. In the case of an int
, the compiler cannot create new int[] { null }
to pass in because that is not valid. Therefore, in order to behave consistently between value types that are not nullable and reference types that are nullable, the compiler has no choice other than to pass in the null array!
Programmer, Engineer