4

我敢肯定论坛上某个地方已经有答案了,但到目前为止我还没有找到。根据此示例,我将匿名方法与委托结合使用,以便使用具有不同参数但返回类型相同的不同方法都用作函数参数:

public delegate TestCaseResult Action();
...

[TestDescription("Test whether the target computer has teaming configured")]
public TestCaseResult TargetHasOneTeam()
{
  // do some logic here and return
  // TestCaseResult
}

[TestDescription("Test whether the target computer has the named team configured")]
public TestCaseResult TargetHasNamedTeam(string teamName)
{
  // do some logic here and return
  // TestCaseResult
}
...

public static void TestThat(TestCaseBase.Action action)
{
  TestCaseResult result = action.Invoke();

  // I want to get the value of the TestDescription attribute here
}
...

// usage
TestThat(() => TargetHasOneTeam());

TestThat(() => TargetHasNamedTeam("Adapter5"));

从示例中可以看出,我真的很希望能够从 TestThat() 函数中获取 TestDescriptionAttribute 属性。我已经浏览了包含我的方法的 Action 参数,但无法“找到”我的 TargetHasOneTeam() 方法。

4

4 回答 4

4

在这种特殊情况下,它基本上是不可访问的。您正在创建一个执行相关方法的 lambda。该 lambda 最终会生成一个新方法,该方法最终是Action委托的参数。该方法与身体中的 IL 指令无关,TargetHasOneTeam而且显然只有当您深入研究身体中的 IL 指令时。

您可以跳过 lambda 并在此处进行方法组转换。

TestThat(TargetHasOneTeam);

现在TargetHasOneTeam被直接分配给委托实例,并且在Delegate::MethodInfo属性中可见。

注意:总的来说,尽管这对于您遇到的问题来说是个坏主意。方法的属性不应影响其满足委托实例化的能力。如果可能的话,我会避免这种类型的检查。

于 2012-05-14T22:54:11.660 回答
4

如果您更改TestThat(() => TargetHasOneTeam())(将您的委托包装到另一个操作中)为 TestThat(TargetHasOneTeam) 并像这样更改 TestThat:

public static void TestThat(TestCaseBase.Action action)
{
  TestCaseResult result = action.Invoke();
  var attrs = action.GetInvocationList()[0].Method.GetCustomAttributes(true);

  // I want to get the value of the TestDescription attribute here
}

会给你你需要的。

用表达式:

public static void TestThat(Expression<Func<TestResult>> action)
{
    var attrs = ((MethodCallExpression)action.Body).Method.GetCustomAttributes(true);

    var result = action.Compile()();
}
于 2012-05-14T23:07:12.957 回答
1

您可以使用 获取任何成员的属性Attribute.GetCustomAttribute。首先检查该属性是否已定义。例如:

public static void TestThat(TestCaseBase.Action action)
{
    TestCaseResult result = action.Invoke();
    if(System.Attribute.IsDefined(action.Method, typeof(TestDescriptionAttribute)))
    {
        var attribute = (TestDescriptionAttribute)System.Attribute.GetCustomAttribute(action.Method,
            typeof(TestDescriptionAttribute));
        Console.WriteLine(attribute.TestDescription);
    }
}
于 2012-05-14T23:03:27.297 回答
0

请参阅MSDN上的此示例。

class TestAuthorAttribute
{
  static void Test()
  {
    PrintAuthorInfo(typeof(FirstClass));
    PrintAuthorInfo(typeof(SecondClass));
    PrintAuthorInfo(typeof(ThirdClass));
  }

  private static void PrintAuthorInfo(System.Type t)
 {
    System.Console.WriteLine("Author information for {0}", t);

    // Using reflection.
    System.Attribute[] attrs = System.Attribute.GetCustomAttributes(t);  // Reflection.

    // Displaying output.
    foreach (System.Attribute attr in attrs)
    {
        if (attr is Author)
        {
            Author a = (Author)attr;
            System.Console.WriteLine("   {0}, version {1:f}", a.GetName(), a.version);
        }
      }
  }
于 2012-05-14T23:35:24.350 回答