【问题标题】:custom attribute changes in .NET 4.NET 4 中的自定义属性更改
【发布时间】:2011-02-26 11:25:26
【问题描述】:

我最近将一个 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() -- 这就是我要找的东西

但是,当我在第二个 CustomAttributeData 实例上调用 GetType() 时,我得到了 {Name = "CustomAttributeData" FullName = "System.Reflection.CustomAttributeData"} System.Type {System.RuntimeType}。如何从CustomAttributeData 中获取TestMethodAttribute,以便从MethodBases 列表中提取测试方法?

【问题讨论】:

    标签: c# unit-testing attributes c#-4.0 custom-attributes


    【解决方案1】:

    我犯了一个愚蠢的错误:我的测试方法提取方法位于引用 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 suggested 在我更新参考后也能正常工作。

    【讨论】:

      【解决方案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() {}
      
      }
      

      【讨论】:

      • 是的,我已经尝试传递true,所以它也检查祖先。我总是得到一个空数组objects。
      • @Sarah:在这种情况下,请发布一个简短但完整的程序来演示该问题。我已经展示了一个确实工作的例子。
      • 虚惊一场!我的项目引用了旧的 .NET 3.5/VS 2008 版本的 UnitTestFramework 库。切换到 .NET 4/VS 2010 版本的 UnitTestFramework (10.0.0.0) 解决了这个问题。
      • @Sarah:啊,对 - 所以反射属性类型与方法上的不同......
      猜你喜欢
      • 2011-01-24
      • 2021-08-02
      • 1970-01-01
      • 1970-01-01
      • 2015-08-08
      • 1970-01-01
      • 2018-12-24
      • 2012-12-24
      • 2014-06-08
      相关资源
      最近更新 更多