c# - 获取在操作中执行的方法的自定义属性

标签 c# lambda action

这是我的示例方法

[TestStep("Do something")]
private void DoSomething()
{   
}

每个看起来像上面的方法都以需要记录方法参数的方式执行:

private void LogStep(Action action)
{
    string stepName = "[" + action.Method.Name + "] ";
    var descr = Attribute.GetCustomAttribute(action.Method, typeof(TestStepAttribute)) as TestStepAttribute;

    if (descr == null)
    {
        this.TestLog.AddWarningMessage(
            (action.Method.DeclaringType == null ? string.Empty : action.Method.DeclaringType.FullName + ".") + action.Method.Name
            + ": missing description");

        return;
    }

    stepName += descr.Description;

    this.TestLog.EndGroup();

    this.TestLog.BeginGroup(stepName);
}

这里我遇到了一个问题。像这样执行 LogStep

LogStep(DoSomething)

完美运行,但是当我使用 lambda 表达式执行它时

LogStep(() => DoSomething())

它告诉我没有 TestStepAttribute 类型的属性在那Action .

乍一看好像很像How do I get the custom attributes of a method from Action<T>?但就我而言,我既不能更改 Action 的类型至 Expression<Action>我也不知道方法名称。

任何建议都会有帮助。

最佳答案

当您使用 lambda 表达式执行它时,lambda 表达式本身就是方法。碰巧在它的主体中有一个方法调用,但那里可能还有其他东西(比如 new object() )。访问此内部方法的属性的唯一方法是将 lambda 表达式作为 Expression 传递。并分析表达式。

为了处理这两种情况,您需要两次重载 LogStep .但是,您不能拥有 LogStep(Action)LogStep(Expression<Action>)因为在调用的同时重载会模棱两可。但如果其中之一是 LogStep(Delegate) 就可以了.

private void LogStep(Delegate action)
{
    var attr = (TestStepAttribute)Attribute
        .GetCustomAttribute(action.Method, typeof(TestStepAttribute));
    Console.WriteLine("LogStep(Delegate action):  " + attr?.Description);
}

private void LogStep(Expression<Action> actionExpr)
{
    string descr = null;
    var methodCall = actionExpr.Body as MethodCallExpression;
    if (methodCall != null) {
        var attribs = methodCall.Method.GetCustomAttributes(typeof(TestStepAttribute), true);
        if (attribs.Length > 0) {
            descr = ((TestStepAttribute)attribs[0]).Description;
        }
    }
    Console.WriteLine("LogStep(Expression<Action> actionExpr):  " + descr);
}

测试:

LogStep(new Action(DoSomething)); // new Action() Is required here. Calls first overlaod.
LogStep(() => DoSomething()); // Calls second overload.
LogStep(() => new object());  // Calls second overload.

请注意,您可以编译和执行 lambda 表达式,以防您需要执行该方法。

关于c# - 获取在操作中执行的方法的自定义属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35362403/

相关文章:

c# - 表达式不能包含 lambda 表达式

loops - Kotlin 中 `break` 中的 `continue` 和 `forEach`

c# - 当前上下文中不存在名称 'form'

c# - 在非托管内存中存储托管引用

c# - 自动生成文档和继承

java - 当我们在 selenium 中有 Actions 类时,为什么我们需要 Robot 类

php - Wordpress 表单未提交

c# - Fortran Dll导入

java - 将谓词应用于 Java 中的 getter 列表

c# - 是否有可能获得一个 Action 中的语句数量或确定它是否有空体?