这是几乎做到这一点的一种方法。缺少的是使用反射,BindingFlags.FlattenHierarchy 不会返回父类的私有方法。将这些类型标记为受保护或公共将解决此问题。(您也可以手动遍历基类来读取私有成员。)
如果您想在程序集中查找声明给定类型的属性的所有类型,您可以编写如下方法:
// using System.Reflection
public IEnumerable<Type> GetTypesWithPropertyOfType(Assembly a, Type t)
{
BindingFlags propertyBindingFlags = BindingFlags.Public
| BindingFlags.NonPublic
| BindingFlags.Instance
| BindingFlags.FlattenHierarchy;
// a property is kept if it is assignable from the type
// parameter passed in
MemberFilter mf = (pi, crit)=>
(pi as PropertyInfo)
.PropertyType
.IsAssignableFrom(t);
// a class is kept if it contains at least one property that
// passes the property filter. All public and nonpublic properties of
// the class, and public and protected properties of the base class,
// are considered
Func<Type, bool> ClassFilter =
c=>c.FindMembers(MemberTypes.Property, propertyBindingFlags, mf, null)
.FirstOrDefault() != null;
// return all classes in the assembly that match ClassFilter
return
a.GetTypes()
.Where(c=>c.IsClass)
.Where(ClassFilter);
}
要在执行程序集中查找定义或继承 type 属性的类type1
,您可以调用:
var v = GetTypesWithPropertyOfType(
Assembly.GetExecutingAssembly(),
typeof(type1));
foreach (var n in v) Console.WriteLine(n.FullName);
这将打印出 foo1。如果定义 foo 类的代码被修改为 (a) make foo1.prop1
public 或 protected,并且 (b) make foo2
inherit from foo1
,那么上面的代码会打印:
foo1
foo2
foo3
正如预期的那样。