2013-04-15 80 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