So I was introduced to the idea of a “guard clause” in methods when I started my latest job. The idea is to make sure that all the passed in parameters of a method are, for example, not null. If they are, just throw an exception. This is what I have been doing:
if(someField == null) { throw new ArgumentNullException(); }
Well just recently I was somewhat schooled in the idea of removing if statements and creating simple methods in their steed. Now this isn’t always a need, but in complex (ie annoying) nested ifs, it might help to clean things up. So in light of this, I came up with this method:
using System; using System.Collections.Generic; using System.Reflection; private void ThrowExceptionIfNull<TException, TObject>(TObject objectToCheck, String message) where TException : Exception where TObject : class { if(objectToCheck == null) { TException exception; exception = Activator.CreateInstance<TException>(); //Set the message field on System.Exception since the property is Get only if(message != null) { List<FieldInfo> fieldInfoList; FieldInfo neededInfo; fieldInfoList = new List<FieldInfo>(typeof(Exception).GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public)); neededInfo = fieldInfoList.Find(currentItem => String.Compare(currentItem.Name, "_message") == 0); //make sure that the message field is still called _message, otherwise //forget the message. if(neededInfo != null) { neededInfo.SetValue(exception, message); } } throw exception; } }
And the use:
ThrowExceptionIfNull<ArgumentNullException, String>(someParameter, "someParameter");
Couple things to keep in mind:
- This uses reflection to find the message field since there is no set accessor to the Message property. This could be dangerous if Microsoft decides to rename the _message field.
- The use of reflection would usually include the caching of the field info since you don’t want to keep using reflection for the same class every time. In this case, you’re throwing an exception so everything is done anyhow. The cost advantage of a cache is pointless.