patterncsharpMinor
NullGuard for throwing more informative exceptions
Viewed 0 times
exceptionsmorethrowingfornullguardinformative
Problem
This small utility class is my solution for a more convenient way for checking against null. I also wanted to have more informative
```
static class NullGuard
{
public static T Check(Expression> expr) where T : class
{
T value = expr.Compile()();
if (value == null)
{
var message = CreateMessage(expr.Body);
throw new NullReferenceException(message);
}
return value;
}
private static string CreateMessage(Expression expr)
{
return CreateMessage(expr as MemberExpression) ?? CreateMessage(expr as MethodCallExpression);
}
private static string CreateMessage(MemberExpression expr)
{
if (expr == null)
{
return null;
}
string instanceName = null;
var constantExpression = expr.Expression as ConstantExpression;
if(constantExpression != null)
{
instanceName = "this";
}
var memberExpression = expr.Expression as MemberExpression;
if (memberExpression != null)
{
instanceName = memberExpression.Member.Name;
}
return CreateMessage(expr.Member.Name, expr.Member.MemberType.ToString(), instanceName);
}
private static string CreateMessage(MethodCallExpression expr)
{
string instanceName = null;
var newExpression = expr.Object as NewExpression;
if (newExpression != null)
{
instanceName = "new " + newExpression.Constructor.DeclaringType.Name;
}
var constantExpression = expr.Object as ConstantExpression;
if (constantExpression != null)
{
instanceName = "this";
}
var memberExpression = expr.Object as MemberExpression;
if (memberExpression != nu
NullReferenceExceptions but I didn't want to pollute my code with null checks everywhere.```
static class NullGuard
{
public static T Check(Expression> expr) where T : class
{
T value = expr.Compile()();
if (value == null)
{
var message = CreateMessage(expr.Body);
throw new NullReferenceException(message);
}
return value;
}
private static string CreateMessage(Expression expr)
{
return CreateMessage(expr as MemberExpression) ?? CreateMessage(expr as MethodCallExpression);
}
private static string CreateMessage(MemberExpression expr)
{
if (expr == null)
{
return null;
}
string instanceName = null;
var constantExpression = expr.Expression as ConstantExpression;
if(constantExpression != null)
{
instanceName = "this";
}
var memberExpression = expr.Expression as MemberExpression;
if (memberExpression != null)
{
instanceName = memberExpression.Member.Name;
}
return CreateMessage(expr.Member.Name, expr.Member.MemberType.ToString(), instanceName);
}
private static string CreateMessage(MethodCallExpression expr)
{
string instanceName = null;
var newExpression = expr.Object as NewExpression;
if (newExpression != null)
{
instanceName = "new " + newExpression.Constructor.DeclaringType.Name;
}
var constantExpression = expr.Object as ConstantExpression;
if (constantExpression != null)
{
instanceName = "this";
}
var memberExpression = expr.Object as MemberExpression;
if (memberExpression != nu
Solution
-
Using a
-
You can greatly simplify your message generation with:
This dumps the passed in expression as a string and you don't have to try and handle all kinds different expressions yourself.
-
Overall I would probably opt for aspect oriented programming (AOP) instead of littering my code with these
Using a
NullReferenceException for this seems wrong since no null reference has been dereferenced - it's capturing expressions which return null when they are not expected to. An InvalidOperationException might fit better (since you are performing an operation on an object which is in an invalid state) or even your own InvalidNullReturnException.-
You can greatly simplify your message generation with:
var message = expr.Body.ToString();This dumps the passed in expression as a string and you don't have to try and handle all kinds different expressions yourself.
-
Overall I would probably opt for aspect oriented programming (AOP) instead of littering my code with these
NullGuard calls. There are a whole number of AOP frameworks around which usually work by using attributes you can decorate your methods and properties with. Based on these attributes arbitrary code can be injected - in your case you could inject the null checking and throwing code. This seems a much less intrusive way of achieving this kind of functionality greatly enhancing readability.Code Snippets
var message = expr.Body.ToString();Context
StackExchange Code Review Q#116653, answer score: 3
Revisions (0)
No revisions yet.