Throwing exceptions often follows the following pattern:
if(condition) { throw exception; }
you check a condition, and if the condition is satisfied, you throw an exception. So, i was wondering if it is good idea to write a static class for it that could look like this:
public static class Throw
{
public static void IfNullOrEmpty<T>(string @string, params object[] parameters) where T : Exception
{
Throw.If<T>(string.IsNullOrEmpty(@string), parameters);
}
public static void IfNullOrEmpty<T, I>(IEnumerable<I> enumerable, params object[] parameters) where T : Exception
{
Throw.If<T>(enumerable == null || enumerable.Count() == 0, parameters);
}
public static void IfNullOrEmpty(string @string, string argumentName)
{
Throw.IfNullOrEmpty(@string, argumentName,
string.Format("Argument '{0}' cannot be null or empty.", argumentName));
}
public static void IfNullOrEmpty(string @string, string argumentName, string message)
{
Throw.IfNullOrEmpty<ArgumentNullOrEmptyException>(@string, message, argumentName);
}
public static void IfNullOrEmpty<I>(IEnumerable<I> enumerable, string argumentName)
{
Throw.IfNullOrEmpty(enumerable, argumentName,
string.Format("Argument '{0}' cannot be null or empty.", argumentName));
}
public static void IfNullOrEmpty<I>(IEnumerable<I> enumerable, string argumentName, string message)
{
Throw.IfNullOrEmpty<ArgumentNullOrEmptyException, I>(enumerable, message, argumentName);
}
public static void IfNull<T>(object @object, params object[] parameters) where T : Exception
{
Throw.If<T>(@object == null, parameters);
}
public static void If<T>(bool condition, params object[] parameters) where T : Exception
{
if (condition)
{
var types = new List<Type>();
var args = new List<object>();
foreach (object p in parameters ?? Enumerable.Empty<object>())
{
types.Add(p.GetType());
args.Add(p);
}
var constructor = typeof(T).GetConstructor(types.ToArray());
var exception = constructor.Invoke(args.ToArray()) as T;
throw exception;
}
}
public static void IfNull(object @object, string argumentName)
{
Throw.IfNull<ArgumentNullException>(@object, argumentName);
}
}
(Note: The ArgumentNullOrEmptyExceptionis not defined here, but it does pretty much what one would expect.)
so instead of repeatedly writing stuff like that
void SomeFunction(string someParameter)
{
if(string.IsNullOrEmpty(someParameter))
{
throw new ArgumentNullOrEmptyException("someParameter", "Argument 'someParameter' cannot be null or empty.");
}
}
i just do
void SomeFunction(string someParameter)
{
Throw.IfNullOrEmpty(someParameter, "someParameter"); // not .IsNullOrEmpty
}
i actually do like it, but is it also a good practice?
You get rid of a bit of code duplication this way (the if … throw), so in that sense it is a good idea. Just be aware that people working on the code would need to know the
ThrowAPI to be able to read and understand the code.One improvement could be to use expression trees to get rid of the string parameter name passing. This would improve the simplicity further, and you wouldn’t have to worry about typing the strings and keeping them correct during refactorings and such.
For instance, on my current pet project I have this Guard class (shortened a bit):
Which I can then use like this: