我想为类的特定属性定义自定义属性。基于反射,应该可以检查属性是否使用此属性进行注释。第一个Assert.AreEqual(2,infos.Length)通过但第二个Assert.AreEqual(1,properties.Count)失败,其中properties.Count = 0.我缺少什么?
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System.Reflection;
namespace Test.UnitTesting.Rest.ParameteterModels
{
public class IncludableAttribute : Attribute
{
}
public class TestClass
{
[Includable]
public List<string> List1 { get; set; }
public List<string> List2 { get; set; }
public TestClass()
{
}
}
[TestClass]
public class IncludeParamaterModelTest
{
[TestMethod]
public void TestMethod1()
{
List<string> properties = new List<string>();
FieldInfo[] infos = typeof(TestClass).GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
Assert.AreEqual(2, infos.Length);
foreach (FieldInfo fi in infos)
{
if (fi.IsDefined(typeof(IncludableAttribute), true)) properties.Add(fi.Name);
}
Assert.AreEqual(1, properties.Count);
}
}
}
类似
答案 0 :(得分:2)
您需要使用GetProperties
代替GetFields
,因为TestClass
中没有任何字段,您有两个自动实现的属性。{ {1}}标记似乎不必要,因为您的属性定义为BindingFlags.NonPublic
。
public
答案 1 :(得分:1)
您的属性正在应用于属性。虽然您有字段,但它们是由编译器创建的 - 并且您的自定义属性未应用于它们。您的代码大致相当于:
[CompilerGenerated]
private List<string> list1;
[Includable]
public List<string> List1 { get { return list1; } set { list1 = value; } }
[CompilerGenerated]
private List<string> list2;
public List<string> List2 { get { return list2; } set { list2 = value; } }
正如您所看到的,仍有两个字段(list1
和list2
) - 这就是您的第一个断言成功的原因。但是,这些都没有Includable
属性。它是List1
属性。
所以你需要要求的是属性而不是字段。我也是用LINQ做的,而不是明确地循环:
var properties = typeof(TestClass)
.GetProperties(BindingFlags.NonPublic |
BindingFlags.Public |
BindingFlags.Instance)
.Where(p => p.IsDefined(typeof(IncludableAttribute), true)
.ToList();
(您可能需要考虑是否真的想要获取非公共属性。)