2012-01-16 87 views
0

我有一种方法可以解析xml并从该xml创建指定类型的对象。 这都是使用泛型完成的,以便为所有类型提供一个通用方法。在类实例中深入查找属性类型

我的问题是,我想使用它的类型名称(而不是名称)在各种类中搜索属性。 可以说,酒店有型“TYPE1”,那么某些类定义的声明如下:

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

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

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

对于所有上述声明的类,如果我创建对象的话,我想访问type1类型属性的每个实例上述的类,即我应该能够从foo1,foo2,foo3类的对象中获得宣称为type1的财产价值。我真的想要一个通用的方法来做到这一点,因为类可能会增加。

回答

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); 
} 

要查找在执行组件定义或继承type1类型的属性等级,你可以拨打:

var v = GetTypesWithPropertyOfType(
      Assembly.GetExecutingAssembly(), 
      typeof(type1)); 

    foreach (var n in v) Console.WriteLine(n.FullName); 

此打印出foo1。如果你的代码定义foo的类被修改为(a)作出foo1.prop1公共或受保护的,和(b)使从foo1foo2继承,那么上面的代码打印:

foo1 
foo2 
foo3 

预期。

+0

如何修改上面的方法来获取类型为“type1”的属性值。请告诉我。我的意图是获取任何类的实例的值。 – rinks 2012-01-17 05:04:34

+0

嘿我得到了另一个解决方案(非反射方法),因为我认为投入这些努力太多了。但感谢您的帮助。 – rinks 2012-01-18 10:54:03