如何查找C#类的内部属性?保护?保护内部?

rya*_*ntm 10 c# system.reflection

如果我有一个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?
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

上面编译的代码是没有任何断言失败的运行.NonPublic返回内部和私有属性.BindingFlags上的其他辅助功能类型似乎没有标志.

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

Jep*_*sen 16

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

  • propertyInfo.GetGetMethod(true).IsPrivate 意味着私人
  • propertyInfo.GetGetMethod(true).IsFamily 意味着保护
  • propertyInfo.GetGetMethod(true).IsAssembly 意思是内在的
  • propertyInfo.GetGetMethod(true).IsFamilyOrAssembly 意味着内部保护

GetSetMethod(true)当然也是类似的.

请记住,让其中一个访问器(getter或setter)比另一个更受限制是合法的.如果只有一个访问者,则其可访问性是整个属性的可访问性.如果两个访问者都在那里,那么容易访问的访问者将为您提供整个属性的可访问性.

propertyInfo.CanRead,看它是否是OK调用propertyInfo.GetGetMethod,并使用propertyInfo.CanWrite查看是否确定调用propertyInfo.GetSetMethod.该GetGetMethodGetSetMethod方法返回null如果访问不存在(或者如果它是非公你问了一个公开).

  • 另一种选择是调用propertyInfo.GetGetMethod(true).即propertyInfo.GetGetMethod(true).IsPrivate.另请注意,我必须像这样调用GetProperties才能使其工作GetProperties(BindingFlags.NonPublic | BindingFlags.Instance); GetProperties(BindingFlags.NonPublic)本身不起作用 (2认同)

500*_*ror 6

在MSDN上查看此文章.

相关报价:

C#关键字protected和internal在IL中没有任何意义,并且不在反射API中使用.IL中的相应术语是Family和Assembly.要使用反射标识内部方法,请使用IsAssembly属性.要标识受保护的内部方法,请使用IsFamilyOrAssembly.