2013-04-15 44 views
10

如果我有如下C#类MyClass如何查找C#类的内部属性?保护?保护内部?

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返回内部和私有属性。在BindingFlags上似乎没有其他辅助功能类型的标志。

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

回答

16

当您与BindingFlags.NonPublic属性的相关信息,你会发现,通过使用分别GetGetMethod(true)GetSetMethod(true)的getter或setter。然后,您可以检查以下属性(方法的信息),以得到确切的访问级别:

  • propertyInfo.GetGetMethod(true).IsPrivate意味着私人
  • propertyInfo.GetGetMethod(true).IsFamily手段保护
  • propertyInfo.GetGetMethod(true).IsAssembly意味着内部
  • propertyInfo.GetGetMethod(true).IsFamilyOrAssembly来保护内部

和当然类似的GetSetMethod(true)

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

使用propertyInfo.CanRead查看是否可以致电propertyInfo.GetGetMethod,并使用propertyInfo.CanWrite来查看是否可以致电propertyInfo.GetSetMethod。如果访问者不存在(或者如果它是非公开的并且您要求公开的),则GetGetMethodGetSetMethod方法将返回null

+2

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

+0

@cgotberg是的,我编辑了我的答案以使用'true'参数。否则,它不会给你非公开的访问者。谢谢。 –

3

GetPropertiesSystem.Reflection.BindingFlags.NonPublic标志回报所有的人:privateinternalprotectedprotected internal

+0

我认为你不能得到更细粒度的。 –

+0

抱歉不清楚。我在我的问题中加了'only'一词,以表明我只想得到那些。 – ryantm

+1

您不能获得比“public”或“nonpublic”更精细的数据。 – MarcinJuraszek

6

请参阅MSDN上的this article

相关报价:

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

+0

这只是关于方法,还是属性? – MarcinJuraszek

+0

我不相信有任何区别。 –

+0

我认为这是因为'IsAssembly'和'IsFamilyAndAssembly'都是在'MethodBase'类中声明的,所以它们在'PropertyInfo'上不可用。 – MarcinJuraszek