【问题标题】:How do I look up the internal properties of a C# class? protected? protected internal?如何查找 C# 类的内部属性?受保护?受保护的内部?
【发布时间】:2013-04-08 02:07:18
【问题描述】:

如果我有一个 C# 类 MyClass 如下:

using System.Diagnostics;

namespace ConsoleApplication1
{
    class MyClass
    {
        public int pPublic {get;set;}
        private int pPrivate {get;set;}
        internal int pInternal {get;set;}
    }
    class Program
    {
        static void Main(string[] args)
        {
            Debug.Assert(typeof(MyClass).GetProperties(
                System.Reflection.BindingFlags.Public |
                System.Reflection.BindingFlags.Instance).Length == 1);
            Debug.Assert(typeof(MyClass).GetProperties(
                System.Reflection.BindingFlags.NonPublic |
                System.Reflection.BindingFlags.Instance).Length == 2);
            // internal?
            // protected?
            // protected internal?
        }
    }
}

上面编译的代码在没有任何断言失败的情况下运行。 NonPublic 返回 Internal 和 Private 属性。 BindingFlags 上似乎没有其他可访问性类型的标志。

如何获得仅包含内部属性的列表/数组?在相关的说明中,但对于我的应用程序来说不是必需的,受保护或受保护的内部呢?

【问题讨论】:

    标签: c# system.reflection


    【解决方案1】:

    当您使用BindingFlags.NonPublic 获取属性信息时,您可以分别使用GetGetMethod(true)GetSetMethod(true) 找到getter 或setter。然后,您可以检查(方法信息的)以下属性以获取确切的访问级别:

    • propertyInfo.GetGetMethod(true).IsPrivate 表示私有
    • propertyInfo.GetGetMethod(true).IsFamily 表示受保护
    • propertyInfo.GetGetMethod(true).IsAssembly 表示内部
    • propertyInfo.GetGetMethod(true).IsFamilyOrAssembly 表示内部受保护
    • propertyInfo.GetGetMethod(true).IsFamilyAndAssembly 表示私有保护

    当然GetSetMethod(true) 也是如此。

    请记住,让其中一个访问器(getter 或 setter)比另一个更受限制是合法的。如果只有一个访问器,它的可访问性就是整个属性的可访问性。如果两个访问器都存在,可访问的访问器为您提供整个属性的可访问性。

    使用propertyInfo.CanRead查看是否可以调用propertyInfo.GetGetMethod,使用propertyInfo.CanWrite查看是否可以调用propertyInfo.GetSetMethodGetGetMethodGetSetMethod 方法返回 null 如果访问器不存在(或者如果它是非公开的并且您要求一个公开的)。

    【讨论】:

    • 另一种选择是调用 propertyInfo.GetGetMethod(true)。即propertyInfo.GetGetMethod(true).IsPrivate。另请注意,我必须像这样调用 GetProperties 才能使其工作 GetProperties(BindingFlags.NonPublic | BindingFlags.Instance); GetProperties(BindingFlags.NonPublic) 本身不起作用
    • @cgotberg 是的,我编辑了我的答案以使用 true 参数。否则它不会给你非公共访问者。谢谢。
    【解决方案2】:

    请参阅 MSDN 上的 this article

    相关引述:

    C# 关键字 protected 和 internal 在 IL 中没有意义,它们是 未在反射 API 中使用。 IL中的相应术语是 家庭和大会。要使用反射识别内部方法, 使用 IsAssembly 属性。要识别受保护的内部方法, 使用 IsFamilyOrAssembly。

    【讨论】:

    • 那只是方法,还是属性?
    • 我不相信有任何区别。
    • 我认为有,因为IsAssemblyIsFamilyAndAssembly 都在MethodBase 类上声明,所以它们在PropertyInfo 上不可用。
    • @MarcinJuraszek 我认为它将在PropertyInfo.GetGetMethod()PropertyInfo.GetSetMethod() 上提供代表底层方法的MethodInfo 对象。此外,您可能需要在传入 true 布尔值的地方点击重载,否则如果属性访问器是非公共的,它将返回 null
    【解决方案3】:

    GetPropertiesSystem.Reflection.BindingFlags.NonPublic 标志返回所有这些:privateinternalprotectedprotected internal

    【讨论】:

    • 我认为你不能再细化了。
    • 抱歉不清楚。我在我的问题中添加了“仅”这个词,以表明我只想得到那些。
    • 您无法获得比publicnonpublic 更精细的数据。
    猜你喜欢
    • 2011-03-11
    • 2011-01-23
    • 2012-03-27
    • 2010-10-30
    • 2011-01-02
    • 2012-09-21
    • 1970-01-01
    • 2011-06-06
    相关资源
    最近更新 更多