I'm really trying to figure out the best practices for reusable code that is easily debugged. I have ran into a common practice among developers that I don't quite understand yet.
public MyConstructor(Object myObject)
{
if (myObject == null)
throw new ArgumentNullException("myObject is null.");
_myObject = myObject;
}
It almost seems unnecessary to do this check. But I think it's because I don't completely understand what the benefits of doing this check are. It seems like a null reference exception would be开发者_如何学JAVA thrown anyway? I am probably wrong, would really like to hear some thoughts on it.
Thank you.
To the compiler, null
is a legitimate constructor argument.
Your class might be able to handle a null value for myObject
. But if it can't - if your class will break when myObject
is null - then checking in the constructor allows you to fail fast.
Passing a null
object is perfectly legal in many cases - for this class the implementor wants to ensure that you cannot create an instance of the class w/o passing a valid Object
instance though, so there have to be no checks later on - it's a good practice to ensure this as early as possible, which would be in the constructor.
if you under 4.0 you can do the following:
public ctor(IEnjection ninjaWeapon)
{
Contract.Requires<ArgumentNullException>(ninjaWeapon != null);
this.deadlyWeaponary.Add(ninjaWeapon);
}
if you under an older version, reference the Microsoft.Contract to do the same thing.
The compilier has no idea about the value of an object, so you have to check this at runtime to ensure it doesn't get called with a null value.
It also depends on your particular solution. You don't need to throw the exception, I would only throw it if you can not have that value be null, and if it is null, that is an exceptional case.
I think that it is not possible to tell generally whether checking for null is necessary or not. It rather depends on whether you can live with null valued variables or not. Null is not per se a bad state. You might have situations where it is allowed for a variable to be null and other where it is not.
Ask yourself whether it makes sense to allow null values or not and design the constructor accordingly.
You could implement a simple ThrowIfNull
extension method to reduce the code you write each time. Jon Skeet covered this in his blog and the referenced SO article here.
Others have already correctly stated that the passing of a null
parameter may or may not be valid depending upon the functionality of the consuming code.
Where a null
parameter is undesirable it is possible, from C# 7.0, to use throw expressions which allow us to rewrite null
checking code much more succinctly as the following example shows:
public MyConstructor(Object myObject)
{
_myObject = myObject ?? throw new ArgumentNullException(nameof(myObject));
}
The above will set the value of _myObject
to the parameter myObject
unless that parameter is null
, in which case an ArgumentNullException
will be thrown.
You need to explicitly check for null because the compiler doesn't know, but also because null can be a valid argument.
The benefit is that the exception will be thrown at the time of object construction, so you can easily trace which part of code is the culprit. If your code requires non-null myobject
value and you don't validate it in the constructor, the NullReferenceException
will be thrown when you use myObject_
and you will have to trace back manually to see who sent that null value in.
精彩评论