在.NET反射中使用BindingFlags.DeclaredOnly和GetProperties()函数

73
抱歉,根据我的职责范围,我不能为您提供该服务。但是,如果您有任何英文方面的问题,我将竭尽所能为您提供帮助。
sometype.GetProperties();

我从类型和其父类获取了所有属性。但是,我只想检索此类型中明确定义的属性(而不是父级的属性)。我认为这就是BindingFlags.DeclaredOnly选项的作用。

然而,当我尝试使用它时:

sometype.GetProperties(BindingFlags.DeclaredOnly);

我得到了0个属性。

有人知道我错在哪里吗?


25
针对所有从谷歌过来的人:如果即使设置标志后仍然无法获取您的“属性”,并且您是C#的新手,并不知道“属性”和“字段”的区别,请尝试使用“GetFields()”。您可能一直在寻找“字段”! - user1306322
1
@user1306322:仅供记录,我“来自谷歌”,我的代码是:var types = type.GetFields.Select(f => f.FieldType).Union(type.GetProperties.Select(p => p.PropertyType)); - 结果仍然为0。 - Veverke
5个回答

94

如果您指定了任何BindingFlags,那么您需要明确指定要获取哪些属性。例如:

sometype.GetProperties (BindingFlags.DeclaredOnly | 
                        BindingFlags.Public | 
                        BindingFlags.Instance);

56

简而言之:

  1. 如果你使用没有参数的 GetProperties() 重载,你将得到所有公共属性

  2. 另一方面,如果你使用接受 BindingFlags 参数的 GetProperties(BindingFlags) 重载,则需要指定以下标志组中至少一个的按位 OR:

    • BindingFlags.Instance / BindingFlags.Static (实例属性 vs 静态属性),
    • BindingFlags.Public / BindingFlags.NonPublic (公共属性 vs 非公共属性)。

例如,要获取公共静态属性,您需要调用 GetProperties(BindingFlags.Public | BindingFlags.Static) 以获取结果。仅调用 GetProperties(BindingFlags.Public)GetProperties(BindingFlags.Static) 将不返回任何结果。

还要注意,指定 BindingFlags.Default 将返回一个空数组

详细信息可以在 MSDN GetProperties(BindingFlags) 文档中找到:

以下 BindingFlags筛选标志可用于定义要包括在搜索中的嵌套类型:

  • 您必须指定 BindingFlags.InstanceBindingFlags.Static 之一,以便获得返回。
  • 指定 BindingFlags.Public 来在搜索中包含公共属性。
  • 指定 BindingFlags.NonPublic 来在搜索中包含非公共方法(即私有、内部和受保护的方法)。仅返回基类上的受保护和内部方法;不返回基类上的私有方法。
  • 指定 BindingFlags.FlattenHierarchy 来在层级结构中包含公共和受保护的静态成员;不包括继承类中的私有静态成员。
  • 以下 BindingFlags 修饰符 标志可用于更改搜索方式:

    • BindingFlags.DeclaredOnly 仅搜索在类型上声明的属性,而不是仅仅继承的属性。

    所以要指出的是:没有任何BindingFlags,会有一些默认值。你知道它们是什么吗? - Stefan Steinegger
    1
    如果使用 GetProperties() 重载(没有参数),您将获得所有公共属性。但是,GetProperties(BindingFlags.Default) 将返回一个空数组。 - vgru
    那么您需要指定一个逻辑或,您是指按位或吗? - rom99
    @rom99:感谢您修复了那个问题。 - vgru
    1
    包括那个神秘枚举的细节,加上➕1。 - Chris Marisic
    显示剩余2条评论

    21

    你需要稍微扩展一下BindingsFlag。至少需要包含可访问级别和实例vs.静态,才能获得有意义的返回内容。

    我认为你实际上正在寻找以下内容

    var flags = BindingFlags.DeclaredOnly 
      | BindingFlags.Instance
      | BindingFlags.Public;
    someType.GetProperties(flags);
    

    0

    来自 MSDN 网站。

    默认情况下 (成员) 没有指定绑定标志。

    您必须指定 Instance 或 Static 以及 Public 或 NonPublic,否则将不返回任何成员。

    因此,除非您指定绑定标志,否则将得到空结果。


    -1

    我在使用typeof(Thing)时遇到了问题,最终我找到了解决方法:

            var thisThing = (new Thing()).GetType();
            foreach (var property in thisThing.GetProperties())
            {
                // ...
            }
    

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接