Here's one way to get what I think you're asking for:
static class Argument
{
public static void NotNull(Expression<Func<Func<object>>> arg)
{
if (arg.Compile()()() == null)
{
var body1 = (Expression<Func<object>>)arg.Body;
var body2 = (MemberExpression)body1.Body;
throw new ArgumentNullException(body2.Member.Name);
}
}
}
Used like this:
void F(string foo)
{
Argument.NotNull(() => () => foo);
The great thing about this is that renaming foo
in the IDE will get all the references. (If you have foo
in a string, it will get missed.)
If you use this in a tight loop, it may cause performance problems, because it calls .Compile()()
each time. You can optimize for performance by adding this overload:
public static void NotNull(object value, Expression<Func<Func<object>>> arg)
{
if (value == null)
{
var body1 = (Expression<Func<object>>)arg.Body;
var body2 = (MemberExpression)body1.Body;
throw new ArgumentNullException(body2.Member.Name);
}
}
Which is used like this:
Argument.NotNull(foo, () => () => foo);
It still gets renames correct, and it saves that call on each iteration.
What I would recommend is using the first version when you write your code, then run it under a profiler, and switch to the second version in the cases that matter.