0

我有一个方法可以解析 xml 并从该 xml 创建一个指定类型的对象。这一切都是使用泛型完成的,以便为所有类型提供通用方法。

我的问题是我想使用其类型名称(而不是名称)在各种类中搜索属性。假设属性的类型为“type1”,那么下面声明了一些类定义:

class foo1
{
  type1 prop1{get;set;}
}

class foo2
{
  foo1 prop2{get;set;}
}

class foo3:foo2
{
  type2 prop3{get;set;}
}

对于上述所有声明的类,如果我创建对象,那么我想访问上述类的每个实例的类型化属性,type1即我应该能够type1从类的对象中foo1获取声明为属性的值。我真的想要一种通用的方法来做到这一点,因为课程可能会增加。foo2foo3

4

1 回答 1

1

这是几乎做到这一点的一种方法。缺少的是使用反射,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.prop1public 或 protected,并且 (b) make foo2inherit from foo1,那么上面的代码会打印:

foo1
foo2
foo3

正如预期的那样。

于 2012-01-16T11:10:14.523 回答