C++的性能C#的產能?! - .Net Native 系列五:.Net Native與反射


   此系列系小九的學堂原創翻譯,翻譯自微軟官方開發向導,一共分為六個主題。本文是第五個主題:.Net Native與反射

  向導文鏈接:C++的性能C#的產能?! - .Net Native 系列:開發向導

 

  [小九的學堂,致力於以平凡的語言描述不平凡的技術。如要轉載,請注明來源:小九的學堂cnblogs.com/xfuture]


   原文:Reflection and .NET Native

 .NET Native與反射

.NET Framework 4.5

    

Note 小貼士

這個主題依賴於預發行的.net native開發者預覽版。下載地址: Microsoft Connect website. 友情提示需要注冊..

  

  .NET Framework框架可以通過反射機制來進行元編程(在編譯時完成部分本應在運行時完成的工作,可提高工作效率)。反射可以動態地創建類型的實例,將類型綁定到現有對象,或從現有對象中獲取類型。然后,可以調用類型的方法或訪問其字段和屬性。支持序列化和反序列化,它支持一個對象的字段先被持久化之后再進行恢復。.NET Framework運行時just-in-time編譯器可以基於可用的元數據來生成本地機器碼。   

  .NET native運行時並不包含JIT編譯器,所以其編譯的機器碼必須是提前生成的。當然有一系列的方法來測試哪些代碼是已經生成的,但是這些規則並不能涵蓋所有的元編程場景。所以需要在運行時提供指令來進行搜索元編程。同時.NET Native並不能將.NET Framework下的私有成員編譯。

  下面將介紹如何使用基於反射的API和運行時指令xml文件的配置:

  

  基於反射的API


  

  在一些情況下你並不能得知代碼中使用了反射而且.NET Native工具並不會保留運行時需要的元數據。本主題所涵蓋的API並不能視為反射的API,但他們是基於反射來執行的。如果你使用這些API的話,需要添加一些信息來運行指令.rd.xml文件,這樣就能正常調用這些API,而且不會導致MissingMetadataException的異常。

  例如:Type.MakeGenericType method

  通過調用這個方法可以在運行時動態生成泛型AppClass<T>

  

var t = Type.GetType("App1.AppClass`1", true);
Type[] typeArgs = {typeof(int)};
Type t2 = t.MakeGenericType(typeArgs);
Activator.CreateInstance(t2);

  為使該代碼能夠成功運行,需要一些元數據支持。首先是在.rd.xml中添加對AppClass<T>的泛型支持

  

<Type Name="App1.AppClass`1" Browse="Required PublicAndInternal" />

  添加后在.NET Framework下就可以調用Type.GetType()方法來獲得對象類型了。

  但在.NET Native下調用就會拋出MissingMetadataException的異常。

  

This operation cannot be carried out as metadata for the following type was removed for performance reasons:

App1.AppClass`1<System.Int32>.

   你可以在運行時指令文件(.rd.xml)添加下面運行指令來激活對Int32的支持:

  

<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" 
                   Activate="Required Public" />

    不同的實例需要不同的指令,添加后就能正常運行。

  類似的方法還有:MethodInfo.MakeGenericMethod method, Array.CreateInstance and Type.MakeTypeArray methods

   所以,在依賴反射的方法使用時,需要添加對反射類型的支持的指令才可以使用。

 

   運行時指令文件(.rd.xml)配置 


  

  運行時指令文件(.rd.xml)是一個xml配置的文件,指定了配置的程序元素是否可用於反射。下面是該文件的一個樣例。

  

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Application>
  <Namespace Name="Contoso.Cloud.AppServices" Serialize="Required Public" />
  <Namespace Name="ContosoClient.ViewModels" Serialize="Required Public" />
  <Namespace Name="ContosoClient.DataModel" Serialize="Required Public" />
  <Namespace Name="Contoso.Reader.UtilityLib" Serialize="Required Public" />

  <Namespace Name="System.Collections.ObjectModel" >
    <TypeInstantiation Name="ObservableCollection" 
          Arguments="ContosoClient.DataModel.ProductItem" Serialize="Public" />
    <TypeInstantiation Name="ReadOnlyObservableCollection" 
          Arguments="ContosoClient.DataModel.ProductGroup" Serialize="Public" />
  </Namespace>
</Application>
</Directives>

  文件結構:

  該文件在 http://schemas.microsoft.com/netfx/2013/01/metadata 命名空間下。

  根元素Directives是指令元素,可以包含一個或者多個Library元素和零個或者一個Application元素,結構如下

  

Directives [1:1]
          Application [0:1]
                     Assembly [0:M]
                                Namespace [0:M]
                                      . . . 
                                Type [0:M]
                                      . . . 
                                TypeInstantiation (constructed generic type) [0:M]
                                      . . . 
                     Namespace [0:M]
                                Namespace [0:M]
                                      . . . 
                                Type [0:M]
                                      . . . 
                                TypeInstantiation (constructed generic type) [0:M] 
                                      . . . 
                     Type [0:M]
                                Type [0:M]
                                      . . . 
                                TypeInstantiation (constructed generic type) [0:M]
                                      . . . 
                                 GenericParameter [0:M]
                                Method [0:M]
                                       Parameter [0:M] 
¶                                      TypeParameter [0:M]
                                     GenericParameter [0:M]
                                MethodInstantiation (constructed generic method) [0:M] 
                                Property [0:M]
                                Field [0:M]
                                Event [0:M]
                     TypeInstantiation (constructed generic type) [0:M]
                                Type [0:M]
                                      . . . 
                                TypeInstantiation (constructed generic type) [0:M]
                                      . . . 
                                Method [0:M]
¶                                       Parameter [0:M] 
¶                                      TypeParameter [0:M]
                                     GenericParameter [0:M]
                                MethodInstantiation (constructed generic method) [0:M]
                                Property [0:M]
                                Field [0:M]
                                Event [0:M]
          Library [0:M]
                     Assembly [0:M]
                                Namespace [0:M]
                                      . . . 
                                Type [0:M]
                                      . . . 
                                TypeInstantiation (constructed generic type) [0:M]
                                      . . . 
                     Namespace [0:M]
                                Namespace [0:M]
                                      . . . 
                                Type [0:M]
                                      . . . 
                                TypeInstantiation (constructed generic type) [0:M] 
                                      . . . 
                     Type [0:M]
                                Type [0:M]
                                      . . . 
                                TypeInstantiation (constructed generic type) [0:M]
                                      . . . 
                                GenericParameter [0:M]
                                Method [0:M]
                                MethodInstantiation (constructed generic method) [0:M] 
                                Property [0:M]
                                Field [0:M]
                                Event [0:M]
                     TypeInstantiation (constructed generic type) [0:M]
                                Type [0:M]
                                      . . . 
                                TypeInstantiation (constructed generic type) [0:M]
                                      . . . 
                                Method [0:M]
                                MethodInstantiation (constructed generic method) [0:M]
                                Property [0:M]
                                Field [0:M]
                                Event [0:M]

   

<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
  <Application>
     <!-- Child elements go here -->  
  </Application>
  <Library Name="Extensions">
     <!-- Child elements go here -->  
  </Library>
</Directives>

   在節點中可以配置需要反射拿到的屬性。具體開發中遇到的反射問題可以參閱之前的一篇文章:C++的性能C#的產能?! - .Net Native 系列《二》:.NET Native開發流程詳解

  由於.NET Native是源生的機器碼,它的目的就在於高效率高性能實現.NET Framework架構開發的應用程序的運行,反射消耗性能較多,盡量少用或者更改其他方法來實現邏輯。

   

  更多.rd.xml信息可以參閱:http://msdn.microsoft.com/en-us/library/dn600639(v=vs.110).aspx

 

  希望大家喜歡這項技術,也可以寫下自己對該技術的展望。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM