深度查找类实例中的属性类型

发布于 2024-12-27 08:45:27 字数 489 浏览 2 评论 0原文

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

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

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

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

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

对于所有上述声明的类,如果我创建对象,那么我想访问该对象的每个实例的 type1 类型属性上面所说的类,即我应该能够从 foo1foo2foo3type1 的属性值代码>类。随着课程的增加,我真的想要一种通用的方法来做到这一点。

I have a method which parses the xml and creates an object of a specified type from that xml.
This is all done using generics so as to have a common method for all types.

My issue is that I want to search for a property in various classes using its type name (not by the name).
Lets say property has a type "type1" then some of the class definition is declared below:

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

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

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

For all the above declared classes, if I create objects then I want to access type1 typed properties for each instance of the above said classes i.e. I should be able to get value of property declared as type1 from objects of foo1, foo2, foo3 classes. I really want a generic way to do this as the classes may increase.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(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) 让 foo2 继承自 foo1 >,然后上面的代码打印:

foo1
foo2
foo3

正如预期的那样。

Here is one way to almost do this. What is missing is that using reflection, BindingFlags.FlattenHierarchy does not return private methods of parent classes. Marking these types as protected or public will resolve this. (You could also manually traverse base classes to read private members.)

If you wanted to find all types in an assembly that declare a property of a given type, you could write a method like:

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

To find classes in the executing assembly that define or inherit a property of type type1, you might call:

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

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

This prints out foo1. If your code defining the foo classes is revised to (a) make foo1.prop1 public or protected, and (b) make foo2 inherit from foo1, then the above code prints:

foo1
foo2
foo3

as expected.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文