C# .NET4中的自定义属性更改
我最近将一个C#项目从.NET3.5升级到了.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
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:啊,没错-所以反射属性类型与方法上的类型不一样。。。