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

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 に答える
4

この特定のケースでは、基本的にアクセスできません。問題のメソッドを実行するラムダを作成しています。そのラムダにより、最終的にActionデリゲートの引数となる新しいメソッドが生成されます。そのメソッドは関係がなくTargetHasOneTeam、本体の IL 命令を掘り下げた場合にのみ明らかになります。

ラムダをスキップして、ここでメソッド グループの変換を行うことができます。

TestThat(TargetHasOneTeam);

現在TargetHasOneTeam、デリゲート インスタンスに直接割り当てられており、Delegate::MethodInfoプロパティに表示されます。

注: 一般的には、これはまさにあなたが遭遇している問題に対しては悪い考えです。メソッドの属性は、デリゲートのインスタンス化を満たす能力に影響を与えるべきではありません。可能であれば、この種の検査は避けたいと思います。

于 2012-05-14T22:54:11.660 に答える
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 に答える