Throwing ArgumentNullException in constructor? - c#

For a constructor with a single parameter, is it OK to throw an ArgumentNullException inside the constructor if the parameter is null/empty? OR, should it be thrown in the method that actually uses the argument? Thanks.

Yes, if it is completely essential then throw the exception. You should not* throw the exception later.
Always remember the "Fail Early Principle". Concept being fail now, so you don't waste time debugging or experience unexpected system functionality.
Alternatively you could also throw a ArgumentException for "" and ArgumentNullException for null. In either case make sure you throw a valid Exception message.
Always a good reference article for managing exceptions: Good Exception Management Rules of Thumb
Side note on what #Steve Michelotti said (because i am a huge fan of CodeContracts)
Contract.Requires<ArgumentNullException>(inputParemeter!= null, "inputparameter cannot be null");
Contract.Requires<ArgumentException>(inputParemeter!= "", "inputparameter cannot be empty string");
alternatively
Contract.Requires<ArgumentNullException>(!string.IsNullOrEmpty(inputParemeter), "inputparameter cannot be null or empty string");

Throwing it in the constructor is fine - there are several classes in the .NET framework that do this. Additionally, check out code contracts for this.

From what it sounds like, you pass in a parameter into the constructor to be held by the class for use in some other method later on. If you're not actually using the argument in the constructor, you should probably think about moving the argument to be a parameter of the method that's actually using it.

I'd put the check in the property that you set when the constructor is called... That way the exception would be thrown in all cases.

Related

Use exception for type mismatch in C#

I am implementing an IDictionary interface, which has parameter object for its get set.
object this [object key] { get; set; }
I want to enforce the key to be type of string, so in my code I do:
(if key.GetType() != typeof(string)) {
//
}
I want to throw an exception when this happen. However I don't know what the most appropriate exception to use in this case. The closest one I can find is TypeInitializationException and ArgumentException. However, it is stated in this document: "Do throw System.ArgumentException or one of its subtypes if bad arguments are passed to a member", which makes me wonder if mine is the right use case for it.
What should I use my case? Should I use Assert instead of throwing Exception?
ArgumentException is the correct exception. The entire BCL uses it and so should you. TypeInitializationException does not fit at all. It has one use case only: a throwing static ctor.
That said, if you are not producing a library (just internal code) you can deviate from that convention if there is a good reason. If you want to use a Debug.Assert or some alternative, feel free to do it.
First I think, the best solution is Mathhew's; Why you just not using the Generic dictionary of type string.
If you need to apply the other approach than Code Contracts is the best way to do that.
Example:
Contract.Requires(key is string);
etc.
Assert is not suitable for this problem but ArgumentException can be applied.
Thanks

Checking for Null in Constructor

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 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.
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.
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.
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.

Proper exceptions to use for nulls

In the following example we have two different exceptions we want to communicate.
//constructor
public Main(string arg){
if(arg==null)
throw new ArgumentNullException("arg");
Thing foo=GetFoo(arg);
if(foo==null)
throw new NullReferenceException("foo is null");
}
Is this the proper approach for both exception types?
The first exception is definitely correct. It's the second one which is tricky.
There are two possibilities here:
GetFoo() isn't meant to return null, ever. In that case we've basically proven a bug in GetFoo(). I'm not sure of the best exception here, leaving ContractException (from Code Contracts) aside. Basically you want something like ContractException - an exception which means "The world has gone crazy: this isn't just an externally unexpected result, there's a bug here."
GetFoo() can legitimately return null, due to arg's value. In this case I would suggest that ArgumentException (but not ArgumentNullException) may be appropriate. On the other hand, it's odd to throw ArgumentException after using the argument.
InvalidOperationException isn't quite appropriate here, but I might be tempted to use it as the closest thing to a contract failure...
EDIT: You should also consider creating your own exception, as per Aaronaught's answer.
You should never explicitly throw a NullReferenceException.
If null was passed as a parameter, you should throw an ArgumentNullException with the name of the parameter.
If some other thing is null, you should probably throw an InvalidOperationException with a descriptive message.
Never throw NullReferenceException. That doesn't mean that a null was passed. It means that there was an attempt to use the null.
The ArgumentNullException is obviously correct and for the second one it depends on your business context.
ArgumentNullException:
The exception that is thrown when a null reference [...] is passed to a method that does not accept it as a valid argument.
NullReferenceException:
The exception that is thrown when there is an attempt to dereference a null object reference.
"foo is null" is a poor error message, since foo is a local variable. A better error message would be "GetFoo returned null for the input " + arg. Also, if an Exception will be thrown whenever GetFoo returns null, make it throw the appropriate exception.
ArgumentNullException is an obvious choice for the first check.
Since it appears that a Thing is derived from an input parameter I would throw an ArgumentException to indicate that a Thing cannot be constructed from the specified input. Afterall, it is (presumably anyway) a problem with the input and not the algorithm used to construct the Thing.
For the first case, I'll pile on and say that ArgumentNullException is correct.
For the second case, I'm really very surprised that nobody else has said this: You should be making your own Exception class for that. None of the built-in system exceptions are really appropriate:
ArgumentException implies that the argument itself was invalid in some way; that's not really the case here. The argument was fine, it's just that something unexpected happened later.
InvalidOperationException is almost correct, but that exception is generally interpreted to mean that an operation was invoked at the wrong time, such as trying to execute a command on a connection that hasn't been opened yet. In other words, it indicates a mismatch between the current state of the object and the specific operation you tried to perform; that's really not applicable here either.
NullReferenceException is right out. That's a reserved exception that means something completely different (that the program actually tried to deference the null reference).
None of these are right. What you really need to be doing is communicated specifically what went wrong, and in order to do that, you should create a MissingThingException. That exception can include the ID of the thing (presumably arg) in its message/detail. This is the best for callers, because it allows them to catch the specific exception if they know how to handle it, and also the best for end users, because it allows you to leave a meaningful error message.
Summary: Create a custom exception class for this.
Per the Code Analysis blog, Exception usage should be as follows:
ArgumentOutOfRangeException if the input value you are testing is not within an expected set of values. (e.g. if the parameter represents a command name, and the provided command name is invalid)
ArgumentNullException if the input value cannot be null in order to execute the function.
ArgumentException if the input value is invalid (e.g. if you pass in an empty string, but empty strings are not allowed)
I think that these are both correct. For me, choosing an exception type is really just about whether or not it will clearly portray the error that has occured. I always think about it from the perspective of another dev that hasn't seen my class before. Will this other dev be provided with enough information to quickly and accurately locate the problem?

What exception type to use when a property cannot be null?

In my application I need to throw an exception if a property of a specific class is null or empty (in case it's a string). I'm not sure what is the best exception to use in this case. I would hate to create a new exception and I'm not sure if ArgumentNullException is appropriate in this case.
Should I create a new exception or there's an exception I can use?
I don't mind to throw an ApplicationException.
The MSDN guidelines for standard exceptions states:
Do use value for the name of the implicit value parameter of property
setters.
The following code example shows a
property that throws an exception if
the caller passes a null argument.
public IPAddress Address
{
get
{
return address;
}
set
{
if(value == null)
{
throw new ArgumentNullException("value");
}
address = value;
}
}
Additionally, the MSDN guidelines for property design say:
Avoid throwing exceptions from
property getters.
Property getters should be simple
operations without any preconditions.
If a getter might throw an exception,
consider redesigning the property to
be a method. This recommendation does
not apply to indexers. Indexers can
throw exceptions because of invalid
arguments.
It is valid and acceptable to throw
exceptions from a property setter.
So throw ArgumentNullException in the setter on null, and ArgumentException on the empty string, and do nothing in the getter. Since the setter throws and only you have access to the backing field, it's easy to make sure it won't contain an invalid value. Having the getter throw is then pointless. This might however be a good spot to use Debug.Assert.
If you really can't provide an appropriate default, then I suppose you have three options:
Just return whatever is in the property and document this behaviour as part of the usage contract. Let the caller deal with it. You might also demand a valid value in the constructor. This might be completely inappropriate for your application though.
Replace the property by methods: A setter method that throws when passed an invalid value, and a getter method that throws InvalidOperationException when the property was never assigned a valid value.
Throw InvalidOperationException from the getter, as you could consider 'property has never been assigned' an invalid state. While you shouldn't normally throw from getters, I suppose this might be a good reason to make an exception.
If you choose options 2 or 3, you should also include a TryGet- method that returns a bool which indicates if the property has been set to a valid value, and if so returns that value in an out parameter. Otherwise you force callers to be prepared to handle an InvalidOperationException, unless they have previously set the property themselves and thus know it won't throw. Compare int.Parse versus int.TryParse.
I'd suggest using option 2 with the TryGet method. It doesn't violate any guidelines and imposes minimal requirements on the calling code.
About the other suggestions
ApplicationException is way too general. ArgumentException is a bit too general for null, but fine otherwise. MSDN docs again:
Do throw the most specific (the most derived) exception that is
appropriate. For example, if a method
receives a null (Nothing in Visual
Basic) argument, it should throw
System.ArgumentNullException instead
of its base type
System.ArgumentException.
In fact you shouldn't use ApplicationException at all (docs):
Do derive custom exceptions from the T:System.Exception class rather than the T:System.ApplicationException class.
It was originally thought that custom exceptions should derive from the ApplicationException class; however, this has not been found to add significant value. For more information, see Best Practices for Handling Exceptions.
InvalidOperationException is intended not for when the arguments to a method or property are invalid, but for when the operation as a whole is invalid (docs). It should not be thrown from the setter:
Do throw a System.InvalidOperationException exception if in an inappropriate state. System.InvalidOperationException should be thrown if a property set or a method call is not appropriate given the object's current state. For example, writing to a System.IO.FileStream that has been opened for reading should throw a System.InvalidOperationException exception.
Incidentally, InvalidOperationException is for when the operation is invalid for the object's current state. If the operation is always invalid for the entire class, you should use NotSupportedException.
I would throw an InvalidOperationException. MSDN says it "is thrown when a method call is invalid for the object's current state."
If the problem is that a member of an argument, and not the argument itself, is null then I think the best choice is the more generic ArgumentException. ArgumentNullException does not work here because the argument is in fact not null. Instead you need the more generic "something is wrong with your argument" exception type.
A detailed message for the constructor would be very appropriate here
Well, it's not an argument, if you're referencing a property of a class. So, you shouldn't use ArgumentException or ArgumentNullException.
NullReferenceException would happen if you just leave things alone, so I assume that's not what you're looking for.
So, using ApplicationExeption or InvalidOperationException would probably be your best bet, making sure to give a meaningful string to describe the error.
It is quite appropriate to throw ArgumentNullException if anyone tries to assign null.
A property should never throw on a read operation.
If it can't be null or empty, have your setter not allow null or empty values, or throw an ArgumentException if that is the case.
Also, require that the property be set in the constructor.
This way you force a valid value, rather than coming back later and saying that that you can't determine account balance as the account isn't set.
But, I would agree with bduke's response.
Does the constructor set it to a non-null value? If so I would just throw ArgumentNullException from the setter.
There is a precedent for stretching the interpretation of ArgumentNullException to meaning "string argument is null or empty": System.Windows.Clipboard.SetText will throw an ArgumentNullException in this case.
So I wouldn't see anything wrong with using this rather than the more general ArgumentException in your property setter, provided you document it.
Just throw whatever as long as the error message is helpful to a developer. This class of exception should never happen outside of development, anyway.

What Exception Type to throw for strings

If I've got the following, really for any string where you check IsNullOrEmpty and it turns up empty, what kind of exception type should one throw, and it's not a argument to a method?
I always have a hard time picking exception types because there are so damn many of them. And this is just grabbing a value from the web.config and checking if SandboxSoapApiUsername returned empty.
if(string.IsNullOrEmpty(ConfigUtility.SandboxSoapApiUsername))
throw new WTF do I throw here??? ahhh
It probably depends on the use/context right? Well I will use the string returned to set a class private field. So I need to check if it's empty string early in the process rather than later (rather than rely on other code to check the property related to the private field I will set ConfigUtility.SandboxSoapApiUsername to).
Since the properties in this class that I'm setting each ConfigUtility.MEthodName to is going to be used in a SOAP request I thought maybe UriFormatException would be appropriate here even though this is not the Uri?
Methods in the .NET Framework usually distinguish between null and an invalid value passed in for an argument. I think you should throw an Argument​Null​Exception if the value is null and an Argument​Exception if it's invalid.
if (arg == null)
throw new ArgumentNullException("arg", "argcannot be null");
if (arg == string.Empty)
throw new ArgumentException("arg cannot be an empty string", "arg");
If the value is not an argument, but, for example, loaded during initialization, I think a Invalid​Operation​Exception would be appropriate:
if (string.IsNullOrEmpty(ConfigUtility.SandboxSoapApiUsername))
throw new InvalidOperationException("Cannot initialize because " +
"SandboxSoapApiUsername not configured");
It depends when the string comes from. An argument might cause an ArgumentNullException. Configuration might throw a ConfigurationException (which seems to be applicable to this case). Or you can of course create your own anyway.
You will really spend most of your time picking from of the list below when throwing a new exception (as opposed to simply doing a throw).
ConfigurationException
The exception that is thrown when a configuration system error has occurred.
ArgumentException
The exception that is thrown when one of the arguments provided to a method is not valid.
InvalidOperationException
The exception that is thrown when a method call is invalid for the object's current state.
1)
This arguably doesn't make sense unless you're picking the setting from an app.config or web.config:
The ConfigurationException exception
is thrown if the application attempts
to read or write data to the
configuration file but is
unsuccessful. Some possible reasons
for this can include malformed XML in
the configuration file, file
permission issues, and configuration
properties with values that are not
valid.
2)
It's not an argument so this one doesn't make much sense.
3)
This is the best of the three as the object will be in an invalid state. However depending on how big your set of configuration settings is, I would prefer to make my own Exception derived from System.Exception.
There's two schools of thought about which to derive from - System.Exception and ApplicationException*. Two different developers on the framework team have expressed different views on which they think you should inherit from, I stick with Jeffrey Richter's view.
If all the above sounds like woffle, then you could just pick one you think is most relevant from the list.
*Looks like MSDN now agrees with its framework devs that ApplicationException was a design mistake
you need an InvalidConfiguration exception - define one
throw new InvalidConfigurationException("Must supply user name")
If its passed as an argument, throw ArgumentNullException.
Otherwise, it really depends on what the string being null means in the context of your application. Don't be afraid to define custom Exception types if there isn't something in the base framework for the scenario.
Since it seems something wasn't configured correctly, I'd suggest System.Configuration.ConfigurationErrorsException.
Note: don't use System.Configuration.ConfigurationException. It's an older version and has been deprecated.
Note 2: Though I'm 90% sure we're dealing with a missing configuration value, if it's an method parameter that's missing, throw an ArgumentException or ArgumentOutOfRangeException.

Categories