1

我最近将一个 C# 项目从 .NET 3.5 升级到 .NET 4。我有一个方法可以从给定的MethodBase实例列表中提取所有 MSTest 测试方法。它的身体是这样的:

return null == methods || methods.Count() == 0
    ? null
    : from method in methods
      let testAttribute = Attribute.GetCustomAttribute(method,
          typeof(TestMethodAttribute))
      where null != testAttribute
      select method;

这在 .NET 3.5 中有效,但自从将我的项目升级到 .NET 4 后,此代码始终返回一个空列表,即使给定包含标记为方法的方法列表也是如此[TestMethod]。.NET 4 中的自定义属性是否发生了变化?

调试时,我发现GetCustomAttributesData()测试方法的结果给出了两个列表,CustomAttributeData在 Visual Studio 2010 的“Locals”窗口中描述为:

  1. Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute("myDLL.dll")
  2. Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()——这就是我要找的

但是,当我调用GetType()第二个CustomAttributeData实例时,我得到{Name = "CustomAttributeData" FullName = "System.Reflection.CustomAttributeData"} System.Type {System.RuntimeType}. 我怎样才能TestMethodAttribute摆脱CustomAttributeData, 以便我可以从MethodBases 列表中提取测试方法?

4

2 回答 2

2

您是否尝试过使用

method.GetCustomAttributes(typeof(TestMethodAttribute), false)

反而?向目标询问自定义属性通常是我获取它们的方式。

这是一个仓促的例子:

using System;
using System.Linq;

[AttributeUsage(AttributeTargets.All)]
public class FooAttribute : Attribute {}

class Test
{
    static void Main()
    {
        var query = typeof(Test).GetMethods()
            .Where(method => method.GetCustomAttributes(
                              typeof(FooAttribute), false).Length != 0);

        foreach (var method in query)
        {
            Console.WriteLine(method);
        }
    }

    [Foo]
    public static void MethodWithAttribute1() {}

    [Foo]
    public static void MethodWithAttribute2() {}

    public static void MethodWithoutAttribute() {}

}
于 2010-06-01T17:46:53.550 回答
2

我犯了一个愚蠢的错误:我的测试方法提取方法位于引用 Microsoft.VisualStudio.QualityTools.UnitTestFramework 的类库项目中,以便它可以TestMethodAttribute作为自定义属性查找。当我将解决方案从 VS 2008 升级到 VS 2010 时,转换过程会自动将我的测试项目中的引用从 Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version= 9.0.0.0更新为 Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version= 10.0.0.0 . 但是,它没有更新我的类库项目中的引用,因此它仍然指向旧的 UnitTestFramework 引用。当我将该项目更改为指向 10.0.0.0 库时,下面的代码按预期工作:

return null == methods || methods.Count() == 0
    ? null
    : from method in methods
      let testAttribute = Attribute.GetCustomAttribute(method,
          typeof(TestMethodAttribute))
      where null != testAttribute
      select method;

此外,一旦我更新了参考,Jon 建议的代码也可以正常工作。

于 2010-06-01T18:07:49.757 回答