C# 学習の振り返り

巴扎黑
リリース: 2016-12-20 17:18:17
オリジナル
1376 人が閲覧しました

1. 反省とは:
反省、中国語訳は反省です。
これは、.Net でランタイム型情報を取得する方法です。.Net アプリケーションは、「アセンブリ」、「モジュール」、「タイプ」といういくつかの部分で構成されており、プログラマがこれらに関する関連情報を取得できるプログラミング方法を提供します。プログラムの実行中にコンポーネントが削除されます。

リフレクションの概要

リフレクションの定義: メタデータを検査し、それに関する型情報を収集する機能。メタデータ (コンパイル後の最も基本的なデータ単位) は、アセンブリまたはモジュールをコンパイルするときに、クラス定義テーブル、フィールド定義テーブル、メソッド定義テーブルなどを作成する多数のテーブルです。 System.reflection 名前空間には、これらのメタデータ テーブルのコードを反映 (解析) できるようにするいくつかのクラスが含まれています。


2. リフレクションの具体的な使用法:

(1) Assembly を使用してアセンブリを定義して読み込み、アセンブリ マニフェストにリストされているモジュールを読み込み、このアセンブリから型を検索してその型のインスタンスを作成します。
(2) モジュールを使用して、モジュールを含むアセンブリとモジュール内のクラスを理解することもできます。また、モジュールで定義されているすべてのグローバル メソッドまたはその他の特定の非グローバル メソッドを取得することもできます。
(3) ConstructorInfo を使用して、コンストラクターの名前、パラメーター、アクセス修飾子 (pulic または private など)、および実装の詳細 (abstract または virtual など) を理解します。 Type の GetConstructors または GetConstructor メソッドを使用して、特定のコンストラクターを呼び出します。
(4) MethodInfo を使用して、メソッドの名前、戻り値の型、パラメーター、アクセス修飾子 (pulic または private など)、実装の詳細 (abstract または virtual など) などを理解します。 Type の GetMethods または GetMethod メソッドを使用して、特定のメソッドを呼び出します。
(5) FiedInfo を使用して、フィールドの名前、アクセス修飾子 (パブリックまたはプライベートなど)、実装の詳細 (静的など) などを理解し、フィールド値を取得または設定します。
(6) EventInfo を使用して、イベントの名前、イベント ハンドラーのデータ型、カスタム プロパティ、宣言型とリフレクション型などを学習し、イベント ハンドラーを追加または削除します。
(7) PropertyInfoを使用して、属性の名前、データ型、宣言型、反映型、読み取り専用か書き込み可能かなどを把握し、属性値を取得または設定します。
(8) ParameterInfoを使用して、パラメータ名、データ型、入力パラメータか出力パラメータか、メソッドシグネチャ内のパラメータの位置などを理解します。


3. リフレクションに関連する名前空間:


System.Reflection.Assembly

System.Reflection.MemberInfo
System.Reflection.EventInfo
System.Reflection.FieldInfo
System.Reflection.MethodBase
System.Reflection。
System.Reflection.MethodInfo
System.Reflection.PropertyInfo
System.Type


4. リフレクション階層モデル:



注: レベル間には 1 対多の関係があります

リフレクションの役割:

1. リフレクションを使用すると、型のインスタンスを動的に作成したり、型を既存のオブジェクトにバインドしたり、既存のオブジェクトから型を取得したりできます
2。 アプリケーションは、リフレクションを使用して特定のタスクを達成できるように、実行時に特定のアセンブリから特定の型を読み込む必要があります。
3. リフレクションは主にクラス ライブラリで使用されます。これらのクラス ライブラリは、より多くの機能を提供するために型の定義を知る必要があります。

アプリケーションポイント:

1. 実際のアプリケーションでは、リフレクション型の使用を必要とするアプリケーションはほとんどありません
2. リフレクション動的バインディングを使用するには、パフォーマンスを犠牲にする必要があります
3. 一部のメタデータ情報はリフレクションでは取得できません
4. 特定のリフレクション型は、CLR のコンパイラを開発する人が使用するために特別に設計されているため、すべてのリフレクション型がすべての人に適しているわけではないことに注意する必要があります。

6. リフレクションの実践的な応用:

appDomain のアセンブリを反映する

static void Main
{
// GetAssemblies を通じて appDomain のすべてのアセンブリを呼び出す
foreach (Assembly assem in Appdomain.currentDomain.GetAssemblies())
{
// 現在のアセンブリの情報を反映する
reflectOnAssembly(assem)
}
}

説明: AppDomain オブジェクトの GetAssemblies メソッドを呼び出すと、System.Reflection.Assembly 要素で構成される配列が返されます。

単一アセンブリの反映

system.reflecton.assembly 型は、次の 3 つのメソッドを提供し、アセンブリの 1 つを明示的に呼び出すことができます。 Load メソッド: 強く推奨されるメソッドです。Load メソッドは、アセンブリ フラグを取得してロードします。Load により、CLR は、グローバル アセンブリ バッファー、アプリケーション ベース ディレクトリ、およびプライベート パスにポリシーを適用します。アセンブリが見つからない場合、システムは例外をスローします。
2. LoadFrom メソッド: アセンブリ ファイルのパス名 (拡張子を含む) を渡すと、アセンブリを指定できない場合、渡されたパラメーターにバージョン番号、カルチャ、および公開キー情報を含めることはできません。指定されたパスで見つかると例外がスローされます。
3. LoadWithPartialName: アプリケーションは読み込まれるアセンブリのバージョンを判断できないため、このメソッドは絶対に使用しないでください。このメソッドの唯一の目的は、.Net Framework のテスト段階で .Net Framework によって提供される特定の動作を使用する顧客を支援することです。このメソッドは最終的には廃止されます。
注: system.AppDomain は Load メソッドも提供します。これは、Assembly の静的 Load メソッドとは異なり、アセンブリへの参照を返します。Assembly の静的 Load メソッドは、値によってアセンブリをカプセル化して送り返します。呼び出し側 AppDomain のロード メソッドの使用を避けるようにしてください

型情報を取得するためにリフレクションを使用する

型情報を取得するためにリフレクションを使用する簡単な例:

システムを使用する;
システム リフレクションを使用する
{
static void Main(string[]args)
{
reflectingreflect=newreflecting();//新しい自己クラスを定義します
//reflecting.exeアセンブリを呼び出します
assembly myAssembly = Assembly.loadfrom("reflecting.exe ")
reflect.getreflectioninfo(myAssembly);// リフレクション情報を取得します
}
// リフレクション内容を取得するメソッドを定義します
void getreflectioninfo(assembly myassembly)
{
type[] typearr= myassemby.Gettypes();//型を取得
foreach (type type in typearr)//各型の詳細情報を取得
{
//型の構造情報を取得
constructorinfo[] myconstructors=type.GetConstructors;
//型のフィールド情報を取得type
fieldinfo[] myfields=type.GetFiedls()
//メソッド情報を取得
MethodInfo myMethodInfo=type.GetMethods();
//プロパティ情報を取得
propertyInfo[] myproperties=type.GetProperties
//イベントを取得情報
EventInfo[] Myevents=type.GetEvents;
}
}
}

型オブジェクトを取得する他のいくつかの方法:

1. System.type パラメーターは文字列型であり、その文字列は型の完全な名前 (名前空間を含む) を指定する必要があります
2。 System.type は、GetNestedType、GetNestedTypes
3 という 2 つのインスタンス メソッドを提供します。 Syetem.Reflection.Assembly 型によって提供されるインスタンス メソッドは、GetType、GetTypes、GetExporedTypes
4 です。 System.Reflection.Moudle は、次のインスタンス メソッドを提供します: GetType、GetTypes、FindTypes

リフレクション タイプのメンバーを設定します

リフレクション タイプのメンバーは、リフレクション階層モデルのデータの最下層です。型のメンバーは、型オブジェクトの GetMembers メソッドを通じて取得できます。パラメーターなしで GetMembers を使用すると、パブリックに定義された型の静的変数とインスタンス メンバーのみが返されます。パラメーターを指定して GetMembers を使用すると、パラメーター設定を通じて指定された型のメンバーを返すこともできます。特定のパラメーターについては、msdn の system.reflection.bindingflags 列挙型の詳細な説明を参照してください。

例:

//返されるタイプのメンバーコンテンツを設定します
bindingFlags bf=bingdingFlags.DeclaredOnly|bingdingFlags.Nonpublic|BingdingFlags.Public;
foreach (MemberInfo mi int t.getmembers(bf))
{
writeline( mi.membertype) // 指定された型メンバーを出力します
}

リフレクションを通じて型のインスタンスを作成します

アセンブリの型はリフレクションを通じて取得でき、型ベースの新しいインスタンスを作成できますこれは、前述した遅延バインディングを実装するために実行時にオブジェクトを作成する機能でもあります。これは次の方法で実現できます:

1. System.Activator の CreateInstance メソッド。このメソッドは、新しいオブジェクトへの参照を返します。
2. System.Activator の createInstanceFrom は前のメソッドと似ていますが、型とそのアセンブリを指定する必要があります。
3. System.Appdomain メソッド: createInstance、CreateInstanceAndUnwrap、CreateInstranceFrom、および CreateInstraceFromAndUnwrap
4. System.type の InvokeMember インスタンス メソッド: このメソッドは、渡されたパラメーターに一致するコンストラクターを返し、型を構築します。
5. System.reflection.constructinfo のインスタンス メソッドを呼び出します

Reflection 型インターフェイスのインスタンス メソッドを呼び出します

型によって継承されたすべてのインターフェイスのコレクションを取得したい場合は、Type の FindInterfaces GetInterface または GetInterfaces を呼び出すことができます。これらすべてのメソッドは、型が直接継承するインターフェイスのみを返すことができ、インターフェイスから継承するインターフェイスは返しません。インターフェイスの基本インターフェイスを返すには、上記のメソッドを再度呼び出す必要があります。

リフレクションのパフォーマンス

リフレクション中、CLR はパラメーターの検証、権限のチェックなど、より多くの作業を実行する必要があり、速度が非常に遅くなります。プログラミングにリフレクションを使用しないようにしてください。動的に構築される型 (遅延バインディング) を作成する予定のアプリケーションの場合は、代わりに次のメソッドを使用できます。クラス継承を通じて。コンパイル時に既知の基本型から型を派生させ、実行時に型のインスタンスを作成し、その型への参照をその基本型の変数に入れてから、基本型の仮想メソッドを呼び出します。
2.インターフェイスを通じて実装されます。実行時に、その型のインスタンスを構築し、そのインターフェイス型の変数にそのインスタンスへの参照を配置し、インターフェイスによって定義された仮想メソッドを呼び出します。
3.委任を通じて達成されました。名前とプロトタイプがコンパイル時に既知のデリゲートと一致するメソッドを型に実装させます。まず実行時にこの型のインスタンスを構築し、次にメソッドのオブジェクトと名前を使用してデリゲートのインスタンスを構築し、デリゲートを通じて必要なメソッドを呼び出します。この方法はより多くの作業を必要とし、前の 2 つの方法よりも効率が低くなります。

使用上の注意:

1. クロスアセンブリ反映

開発中、B.dll の型を A.dll に反映する必要があるため、注意しないとランタイムに反映されません。エラーが発生します。アセンブリ間リフレクションに関しては、次の 2 つの点に注意してください:

(1) typeof を使用し、コンパイルが通過できる場合は、アセンブリ間リフレクションが正常に実行される必要があります。 typeof は強い型付けをサポートしていると言えます。たとえば、


Type supType = typeof(EnterpriseServerBase.DataAccess.IDBAccesser);

現在のアセンブリが EnterpriseServerBase.dll への参照を追加しない場合、コンパイルでエラーが報告されます。

(2) Type.GetType を使用する場合、Type.GetType は厳密に型指定されていないため、状況はさらに複雑になります。 Type.GetType のパラメーターが文字列である場合、string で表されるターゲットの型が現在のアセンブリにない場合、Type.GetType は実行時に null を返します。解決策は、まずターゲット アセンブリを読み込んでから、Assembly.GetType メソッドを使用することです。例:

Assembly asmb = Assembly.LoadFrom("EnterpriseServerBase.dll") ;

Type supType = asmb.GetType("EnterpriseServerBase.DataAccess.IDBAccesser") ;


Type.GetType を使用する場合は、For を追加した場合でも注意してください。 EnterpriseServerBase.dll への参照、Type.GetType("EnterpriseServerBase.DataAccess.IDBAccesser") も null を返します。これは、Type.GetType が現在のアセンブリでのみ型検索を実行するためです。

2. リフレクション中にメソッドの戻り値の型が void であるかどうかを判断します

Type serviceType = typeof(T);

MethodInfo methodInfo = serviceType.GetMethod(methodName);

methodInfo.ReturnType == typeof(void) であるかどうかを判断します本当です それはそれです。

関連ラベル:
c
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート