BlakeH
BlakeH

Reputation: 3494

Performance implications of Expression.Compile for argument null checks

We are trying to find a more refactor-friendly way of testing for null arguments in our methods so that instead of writing:

if (arg1 == null)
{
    throw new ArgumentNullException("arg1")
}

thing1 = arg1;

our developers can do something like

thing1 = ArgumentNotNull(() => arg1);

Here is the code for ArgumentNotNull in the above example:

    public static void ArgumentNotNull<T>(Expression<Func<T>> member)
        where T : class
    {
        var argumentName = ((MemberExpression)member.Body).Member.Name;
        var func = member.Compile();
        var argumentValue = func();

        if (argumentValue == null)
        {
            throw new ArgumentNullException(argumentName);
        }
    }

The one question I have with the way we are doing this is: Is Expression.Compile() prohibitively expensive to do for something as trivial as this check?

I have a feeling that we might see some problems down the road as both the number of arguments and calls to methods increase...

Upvotes: 1

Views: 81

Answers (1)

Haney
Haney

Reputation: 34852

The .Compile() call is very expensive, but can be mitigated by caching the compiled method in something like a static Dictionary<TKey, TValue> where the key is the type of member. This way, your first call would be slow and the rest would be just about as fast as a regular method call, since you'd be reusing your method for future checks on a given type. Downside: possible memory bloat or leak for a lot of different types.

Upvotes: 2

Related Questions