C# .NET4中的自定义属性更改

C# .NET4中的自定义属性更改,c#,unit-testing,attributes,c#-4.0,custom-attributes,C#,Unit Testing,Attributes,C# 4.0,Custom Attributes,我最近将一个C#项目从.NET3.5升级到了.NET4。我有一个方法可以从给定的MethodBase实例列表中提取所有MSTest测试方法。它的身体是这样的: return null == methods || methods.Count() == 0 ? null : from method in methods let testAttribute = Attribute.GetCustomAttribute(method, typeof(Tes

我最近将一个C#项目从.NET3.5升级到了.NET4。我有一个方法可以从给定的
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”窗口中描述为:

  • Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute(“myDLL.dll”)
  • Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute()
    ——这就是我要找的
  • 然而,当我在第二个
    CustomAttributeData
    实例上调用
    GetType()
    时,我得到
    {Name=“CustomAttributeData”FullName=“System.Reflection.CustomAttributeData”}System.Type{System.RuntimeType}
    。如何从
    CustomAttributeData
    中获取
    TestMethodAttribute
    ,以便从
    MethodBase
    列表中提取测试方法?

    您是否尝试过使用

    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() {}
    
    }
    
    你试过使用吗

    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() {}
    
    }
    

    我犯了一个愚蠢的错误:我的测试方法提取方法位于一个类库项目中,该项目引用了Microsoft.VisualStudio.QualityTools.UnitTestFramework,因此它可以将
    TestMethodAttribute
    作为自定义属性查找。当我将解决方案从VS 2008升级到VS 2010时,转换过程会自动将测试项目中Microsoft.VisualStudio.QualityTools.UnitTestFramework(版本=9.0.0.0的引用更新为Microsoft.VisualStudio.QualityTools.UnitTestFramework(版本=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;
    

    此外,一旦我更新了引用,代码也能正常工作。

    我犯了一个愚蠢的错误:我的测试方法提取方法位于一个类库项目中,该项目引用了Microsoft.VisualStudio.QualityTools.UnitTestFramework,以便它可以将
    TestMethodAttribute
    作为自定义属性。当我将解决方案从VS 2008升级到VS 2010时,转换过程会自动将测试项目中Microsoft.VisualStudio.QualityTools.UnitTestFramework(版本=9.0.0.0的引用更新为Microsoft.VisualStudio.QualityTools.UnitTestFramework(版本=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;
    

    而且,一旦我更新了引用,代码也能正常工作。

    是的,我已经尝试传递
    true
    ,所以它也会检查祖先。我总是得到一个空的
    object
    s数组。@Sarah:那样的话,请发布一个简短但完整的程序来演示这个问题。我已经展示了一个有效的例子。假警报!我的项目引用了UnitTestFramework库的旧.NET3.5/VS2008版本。切换到.NET 4/VS 2010版的UnitTestFramework(10.0.0.0)修复了这个问题。@Sarah:啊,对-所以反射属性类型与方法上的类型不同…是的,我尝试传递
    true
    ,所以它也会检查祖先。我总是得到一个空的
    object
    s数组。@Sarah:那样的话,请发布一个简短但完整的程序来演示这个问题。我已经展示了一个有效的例子。假警报!我的项目引用了UnitTestFramework库的旧.NET3.5/VS2008版本。切换到.NET 4/VS 2010版的UnitTestFramework(10.0.0.0)修复了这个问题。@Sarah:啊,没错-所以反射属性类型与方法上的类型不一样。。。