获取被叫方的扩展方法名称

时间:2016-02-09 09:33:40

标签: c#

我已经构建了一个简单的ArgumentValidator类,以简化任何给定方法中的参数前置条件。它们中的大多数都是null或边界检查,经过几次

后变得相当繁琐
if (arg == null ) throw new ArgumentNullException(nameof(arg));

所以我想出了以下设置:

public static class ArgumentValidator
{
    public interface IArgument<T>
    {
        string ParamName { get; }
        T Value { get; }
    }

    private class Argument<T>: IArgument<T>
    {
        public Argument(T argument, string paramName)
        {
            ParamName = paramName;
            Value = argument;
        }

        public string ParamName { get; }
        public T Value { get; }
    }

    public static IArgument<T> Validate<T>(this T argument, string paramName = null)
    {
        return new Argument<T>(argument, paramName ?? string.Empty);
    }

    public static IArgument<T> IsNotNull<T>(this IArgument<T> o)
    {
        if (ReferenceEquals(o.Value, null))
            throw new ArgumentNullException(o.ParamName);

        return o;
    }

    public static IArgument<T> IsSmallerThan<T, Q>(this IArgument<T> o, Q upperBound) where T : IComparable<Q> { ... }

    //etc.
}

我可以通过以下方式使用它:

public Bar Foo(object flob)
{
     flob.Validate(nameof(flob)).IsNotNull().IsSmallerThan(flob.MaxValue);
}

理想情况下,我希望在nameof(flob)电话中摆脱Validate,最终完全摆脱Validate; Validate的唯一目的是避免在链上的每次检查中都必须通过nameof(...)

有没有办法在flob方法中获取名称Validate()

1 个答案:

答案 0 :(得分:3)

使用扩展方法做到这一点并不容易。使用带有LINQ表达式(源自devdigital's answer here)的静态方法更容易:

.class

public static T Validate<T>(this Expression<Func<T>> argument) { var lambda = (LambdaExpression)argument; MemberExpression memberExpression; if (lambda.Body is UnaryExpression) { var unaryExpression = (UnaryExpression)lambda.Body; memberExpression = (MemberExpression)unaryExpression.Operand; } else { memberExpression = (MemberExpression)lambda.Body; } string name = memberExpression.Member.Name; Delegate d = lambda.Compile(); return (T)d.DynamicInvoke(); } inside是您在方法中输入的属性的名称:

name

由于MyMethods.Validate(() => o); 返回Validate,您可以进一步使用它。这可能没有你想要的那样,但这是唯一可行的选择。

也可以将其作为扩展方法,您必须自己手动创建表达式:

T