.NET 4.5のリフレクションの新機能

.NET 4.5には、System.Reflectionに対するいくつかの変更が含まれています。 これらの最も重要な点は、TypeがTypeとTypeInfoの2つの個別のクラスに分割されたことです。 TypeInfoオブジェクトには完全な定義が格納され、Type自体には共通データのみが格納されるようになりました。 NET 4.5でデスクトップまたはWebアプリケーションからのリフレクションを使用する場合、古いリフレクションメソッドとともに古いAPIを引き続き使用できます。 今日は、新しいAPIのコア機能の使用方法に焦点を当てます。



TypeとTypeInfoの概要



Typeクラスは、オブジェクトの構造の一般的な概念を提供します。 一方、TypeInfoは、親および継承されたクラスとの関係を含む、オブジェクトの完全な定義を提供します。 さらに、TypeクラスのAPIが更新され、以前の配列ではなく、型付きIEnumerableの形式でコレクションを返すようになりました。 大規模で複雑なアセンブリの場合、これにより、リフレクション結果の値を一度に1つずつ読み取ることができ、LINQを使用して型メタデータの使用を簡素化することもできます。 Windowsストアアプリは、これらの新しいIEnumerableコレクションにのみアクセスできます。



型クラスAPIの変更



TypeInfoを使用せずにTypeから取得できるメタデータを見て、TypeInfo APIに飛び込みましょう。 Type APIは一般的なタイプ情報を提供します。 これは、名前、名前空間、フルネーム、モジュールなどのメタデータを取得できることを意味します。 これは、.NET 4.0と同じAPIを介して行われます。 たとえば、あるタイプのフルネームとネームスペースを取得するには、次の操作を実行できます。



Type stringType = typeof(string); string fullName = stringType.FullName; string stringNameSpace = stringType.Namespace;
      
      







TypeInfo API



ご覧のとおり、Typeはクラスの構造の一般的なアイデアを提供します。 さらに深く掘り下げたい場合は、新しいTypeInfoクラスAPIを使用できます。 GetTypeInfo()メソッドを呼び出すことにより、TypeからTypeInfo値を取得できます。 たとえば、名(FirstName)、姓(LastName)、Modifiedイベント、およびSaveメソッドのプロパティを含むPersonクラスを取り上げます。



 public class Person { public string FirstName { get; set; } public string LastName { get; set; } public event EventHandler Modified; public void Save() { //    ... } }
      
      







ここで、Personクラスで定義されているプロパティ、メソッド、イベントを知る必要があるとしましょう。 これは、そのDeclaredProperties、DeclaredMethods、およびDeclaredPropertiesプロパティを使用してTypeInfoから簡単に学習できます。



 TypeInfo personInfo = personType.GetTypeInfo(); IEnumerable<PropertyInfo> declaredProperties = personInfo.DeclaredProperties; IEnumerable<MethodInfo> declaredMethods = personInfo.DeclaredMethods; IEnumerable<EventInfo> declaredEvents = personInfo.DeclaredEvents;
      
      







リフレクションのもう1つの一般的なタスクは、アセンブリ内のすべてのタイプを見つける必要があることです。 更新されたSystem.Reflection APIを使用して、AssemblyクラスはType配列ではなくTypeInfoコレクションを返すようになりました。 たとえば、実行中のアセンブリで定義されているすべての型を取得するには、TypeInfo.Assemblyプロパティを使用して、結果のAssemblyオブジェクトのDefinedTypesプロパティを読み取ります。



 Assembly myAssembly = this.GetType().GetTypeInfo().Assembly; IEnumerable<TypeInfo> myTypes = myAssembly.DefinedTypes;
      
      







新しいSystem.Reflection APIをよりよく理解するために、実行中のアセンブリ内のすべてのタイプのリストを取得するサンプルアプリケーションを作成しましょう。 そして、タイプを選択すると、その名前、フルネーム、プロパティ、メソッド、イベントが表示されます。



アプリケーションを作成する



開始するには、前に説明したように、新しいC#Windowsストアアプリケーションを作成し、そこにPersonのクラスを追加します。 次に、 MainPage.xamlを開き、 そのXAMLをグリッドのルート要素として追加ます。



次に、MainPageクラスを更新して、実行中のアセンブリで定義されている型のリストをコンパイルします。 最初にusing System.Reflection



using System.Reflection



てファイルの先頭に追加using System.Reflection



ます。 次に、 OnNavigateTo



メソッドを更新して、アプリケーションアセンブリから取得した型を受け取り、それらをMyDefinedTypes



リストにバインドします。



 protected override void OnNavigatedTo(NavigationEventArgs e) { Assembly myAssembly = this.GetType().GetTypeInfo().Assembly; IEnumerable<TypeInfo> myTypes = myAssembly.DefinedTypes; MyDefinedTypes.DataContext = myTypes; }
      
      







これで、 MyDefinedTypes



MyDefinedTypes



要素のSelectionChanged



イベントを、 TypeInfoDetails



パネルで選択したTypeInfoを表示するハンドラーにTypeInfoDetails



です。



 private void MyDefinedTypes_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (e.AddedItems.Count > 0) { TypeInfo selectedTypeInfo = e.AddedItems.First() as TypeInfo; TypeInfoDetails.DataContext = selectedTypeInfo; TypeInfoDetails.Visibility = Windows.UI.Xaml.Visibility.Visible; } }
      
      







最終的なフォームでは、MainPageクラスは次のようになります



おめでとうございます! アプリケーションの準備が整い、実行時に次の結果が表示されます。





ご覧のとおり、TypeクラスのAPIには非常に重要な変更があります。 これは、以前のバージョンの.NETからアップグレードしていて、新しいAPIのみが利用可能なWindowsストアアプリケーションを作成する場合に特に重要です。 このAPIは、通常のデスクトップおよび.NET 4.5 Webアプリケーション、およびポータブルクラスライブラリプロジェクトでも使用できます。 新しいAPIは、配列の代わりにIEnumerableを使用し、一般的な反射データと詳細な反射データを2つのクラス(TypeとTypeInfo)に分離したおかげで、よりクリーンになったと思います。



All Articles