从该方法中获取变量调用方法的名称

时间:2013-08-11 18:29:39

标签: c#

我想为对象创建一个扩展方法,检查对象是否为null并抛出异常(如果是)。我想保留原始变量名称。我可以以某种方式从扩展方法中获取它吗?必须写customer.NotNull("customer") vs customer.NotNull()

,这是“麻烦的”

3 个答案:

答案 0 :(得分:1)

不,不幸的是你不能。变量名在运行时不可用。但是,您可以使用以下表达式:

void NotNull<T>(Expression<Func<T>> expression)
{
    var me = expression.Body as MemberExpression;
    var name = me.Member.Name;
    var value = expression.Compile().Invoke();
    ...
}


NotNull(() => customer);

答案 1 :(得分:0)

// using System.Diagnostics.Contracts;
using System.Linq.Expressions;

static void ThrowIfNull<T>(Expression<Func<T>> expr) where T : class
{
    // Contract.Requires(expr != null);
    // Contract.Requires(expr.Body.NodeType == ExpressionType.MemberAccess);
    if (((object)expr.Compile().Invoke()) == null)
    {
        throw new ArgumentNullException(((MemberExpression)expr.Body).Member.Name);
    }
}

然后这样称呼:

object someVariable = null;
ThrowIfNull(() => someVariable);  // will throw an ArgumentNullException 
                                  // with paramName == "someVariable"

PS:我不确定这是不是一个好主意:首先构建一个表达式树,然后在每次调用此方法时编译它都会产生开销,只是为了让你可以检查变量是否包含null引用,如果是,则检索变量名称。像void ThrowIfNull<T>(T arg, string paramName)这样的东西不是那么好,但可能表现得更好!

答案 2 :(得分:0)

正如另一个所说,但请注意,编译表达式是一件很慢的事情......所以这个变量接收值作为参数。你必须写更多,但对于被称为百次的方法,它可能会更好。

[DebuggerHidden]
public static void NotNull<T>(T value, Expression<Func<T>> exp) where T : class
{
    if (value != null)
    {
        return;
    }

    var body = exp.Body as MemberExpression;

    if (body == null)
    {
        throw new ArgumentException("Wrongly formatted expression");
    }

    throw new ArgumentNullException(body.Member.Name);
}

用法:

NotNull(str, () => str);

[DebuggerHidden]是调试器不会进入该方法的。最后,如果方法抛出,通常是因为你传递的内容,而不是方法中的内容。