プログラム操作の図:
リフレクションを理解する前に、次の図に示すように、まずプログラムの実行プロセスを理解してください。
プログラマーは高水準言語(c#、vbなど)を作成し、コンパイラーによってコンパイルされた後、DLLまたはEXEファイルが生成され、JITによってマシンコードにコンパイルされ、最終的にコンピューターによって実行されます。
細分化されている場合、DLL / EXEファイルにはメタデータと中間言語が含まれています。これらはJITによってマシンコードにコンパイルされます。
メタデータはデータリストとして理解できます。CLRはDLL / EXEを実行するときに、最初にメタデータを検索します。メタデータは、含まれる名前名、名前空間に含まれるクラスなど、DLL / EXEの詳細情報を記述します。 、および「メソッドとは何か」のクラスとそこにあるプロパティ。
反射の概念:
Reflection:System.Reflectionは、.Net Frameworkによって提供されるヘルパーライブラリであり、meatdata(メタデータ)を読み取って使用できます。
リフレクションの最初の経験:
.netコードでは、カスタムクラスライブラリをロードする場合、3つのステップが必要です。最初のステップはプロジェクト内のクラスライブラリへの参照を追加することであり、2番目のステップはでクラスライブラリの名前空間を使用することです。コード、および3番目のステップはクラスライブラリのメソッドを呼び出すことです。
リフレクションを使用してこのステップを実行する場合は、参照ステップを追加する必要はありません。アセンブリをメモリに直接ロードして、内部の情報を読み取ることができます。次の例に示すように:
インターフェイスをカスタマイズします。
namespace DB.Interface
{
/// <summary>
/// 数据访问类
/// </summary>
public interface IDBHelper
{
void Query();
}
}
MySqlクラスをカスタマイズします。
using DB.Interface;
using System;
namespace DB.MySql
{
public class MySqlHelper : IDBHelper
{
public void Query()
{
Console.WriteLine("{0}.Query", this.GetType().Name);
}
public MySqlHelper()
{
Console.WriteLine("{0}被构造", this.GetType().Name);
}
}
}
プログラムの主な方法:
using DB.MySql;
using System;
using System.Reflection;
namespace MyReflection
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("***********************常规用法************************");
MySqlHelper mySqlHelper = new MySqlHelper();
mySqlHelper.Query();
Console.WriteLine("***********************反射用法************************");
//将dll加载到内存中
Assembly assembly = Assembly.Load("DB.MySql");//程序集的名称
foreach (var type in assembly.GetTypes())
{
Console.WriteLine("第一次循环:" + type.Name);
foreach (var method in type.GetMethods())
{
Console.WriteLine(method.Name);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.Read();
}
}
}
プログラムは、従来の書き込みとリフレクション書き込みを使用して、インスタンスの名前とメソッドの名前をそれぞれ出力します。実行結果は次のとおりです。
すべて、MySqlHelperのクラス名と、Queryメソッドの名前が出力されました。
リフレクションの例では、ToStringなどのメソッドの名前も出力されます。これらは、実際にはObjectのメソッドです。
反射使用:
リフレクションの役割は、アセンブリの内容を表示することだけでなく、アセンブリを使用することもできます。つまり、メソッドを呼び出すことができます。
Type type = assembly.GetType("DB.MySql.MySqlHelper");//获取类型
dynamic dDBHelper= Activator.CreateInstance(type);//创建对象
dDBHelper.Query();//调用对象的方法
実行結果を図に示します。
通常の参照メソッドのように、インスタンス内のメソッドを呼び出すことができます。
手順は次のように分割できます。1。アセンブリタイプを取得します。2。オブジェクトを作成します。3。オブジェクトメソッドを呼び出します。
これはそれほど単純ではないようです。リフレクション関連のメソッドのパッケージを作成できます。
using DB.Interface;
using System;
using System.Reflection;
using System.Configuration;
namespace MyReflection
{
/// <summary>
/// 定义一个工厂
/// </summary>
public class SimpleFactory
{
//static关键字表示'静态',它的作用是当程序第一次调用类的时候完成初始化,就执行一次,而且只会执行一次。
private static string IDBHelperConfig = ConfigurationManager.AppSettings["IDBHelperConfig"];
private static string DllName = IDBHelperConfig.Split(',')[0];
private static string TypeName = IDBHelperConfig.Split(',')[1];
public static IDBHelper CreateInstance()
{
Assembly assembly = Assembly.Load(DllName);//程序集的名称
Type type = assembly.GetType(TypeName);//获取类型
object oDBHelper = Activator.CreateInstance(type);//创建对象
IDBHelper iDBHelper = oDBHelper as IDBHelper;
return iDBHelper;
}
}
}
App.configファイルで構成を行う必要があります。
<appSettings>
<add key = "IDBHelperConfig" value = "DB.MySql、DB.MySql.MySqlHelper" />
</ appSettings>
これは、参照されるアセンブリ名の変更を容易にするためです。
呼び出し場所は次のように書くことができます:
IDBHelper dBHelper = SimpleFactory.CreateInstance();
dBHelper.Query();
実行結果はまだです:
総括する:
リフレクションの重要性は、プログラムの拡張を実現するためにアセンブリを動的にロードできることです。
上記の内容は私の個人的な理解であり、いくつかのエラーまたは不完全性があるかもしれません。