リフレクションおよびリフレクションアプリケーションと呼び出しメソッドとは
序文
1. ILspy:リバースエンジニアリング:Dll / Exeファイルを逆コンパイルできます;2。IL:
C#コードでマークされたコードであり、読みにくいです
3.メタデータ:データのリストであり、そこにあるものを記録するだけで、すべての実装を表示します。詳細な元帳
4.ReflectionはSystem.Reflection名前空間で、メタデータを読み取ってメタデータを使用できます。これはMicrosoftが提供するヘルパーライブラリです
。5。次の図は、ILSpyを使用して作成したエンティティクラスを開く例を示しています。ILメソッドを使用する場合、表示されるプログラムはあまり明確ではありません。
6. C#を使用して表示すると、最初に作成したコードを取得できます。
なぜ反射を学ぶのか
回答:リフレクションは本当にどこにでもあるので、ORM / MVC / IOC;
- MVCプログラミングでは、「ホーム/インデックス」などのパスを使用して、プログラムファイル内の特定のクラスにアクセスします。実用的なのは反射です。
- リフレクションを使用してエンティティオブジェクトを生成できます。
- リフレクションを使用して、自動クエリステートメントを生成し、エンティティクラスに基づいてオブジェクトを返すことができます。
- リフレクションは、プログラムの分離を実現できます(クラスはプロジェクト参照を追加せずに使用できます)。
- リフレクションは、動的構成を実現して、プログラムの高可用性を実現できます。
1.オブジェクトを作成するためのリフレクション
1.現在の構造は上記のとおりです。呼び出し方法は、図とコードに示すとおりです。
2. dll動的ライブラリをロードする方法はたくさんあります。この方法を使用することをお勧めしますAssembly.LoadFrom理由:
- dllへの参照を追加する必要はありません。使用するには、dllをリリースディレクトリにコピーするだけです。
- フルパスは必要ありません。DL1の名前を入力するだけです。PS:サフィックスは.dllで追加する必要があります
public static IDBHelper getClass()
{
//获取数据清单metadata
Assembly assembly3 = Assembly.LoadFrom(@"HomeWork.SqlHelper.dll"); //dll名称(需要后缀)
///2.获取类型
Type type = assembly3.GetType("HomeWork.SqlHelper.SqlServerHelper");
//创建实例
object obj = Activator.CreateInstance(type);
//类型转换。
return obj as IDBHelper;
}
2.リフレクション呼び出しメソッド
通过在上边的简单工厂后,我们实例出来一个接口对象IDBHelper。
接下来就可以通过接口点方法进行使用。
Console.WriteLine("获取反射类开始!");
IDBHelper iDBHelper = SimpleFactory.getClass();
5.调用方法
Company company = iDBHelper.Find(1);
Console.WriteLine("获取反射类完成!");
3.リフレクトしてパラメータを使用して構築メソッドを呼び出します
{
Console.WriteLine("*********************Reflection创建带构造函数参数的对象*************************");
Assembly assembly3 = Assembly.LoadFrom("HomeWork.SqlHelper.dll"); //dll名称(需要后缀)
Type type = assembly3.GetType("HomeWork.SqlHelper.SqlServerHelper");
object obj = Activator.CreateInstance(type);
object obj1 = Activator.CreateInstance(type, new object[] {
"你好" });
object obj2 = Activator.CreateInstance(type, new object[] {
123 });
object obj3 = Activator.CreateInstance(type, new object[] {
123, "你好" });
Type type1 = typeof(SqlServerHelper);
}
4.リフレクション呼び出しメソッド
{
//Type type1 = typeof(ReflectionTest);
//普通调用方式
ReflectionTest reflectionTest = new ReflectionTest();
reflectionTest.Show1();
reflectionTest.Show2(123);
reflectionTest.Show3(123);
//reflectionTest.Show4
ReflectionTest.Show5("Richard");
//Console.WriteLine("*********************Reflection调用普通方法*************************");
Assembly assembly3 = Assembly.LoadFrom("HomeWork.SqlHelper.dll"); //dll名称(需要后缀)
Type type = assembly3.GetType("HomeWork.SqlHelper.ReflectionTest");
object objTet = Activator.CreateInstance(type);
//objTet.Show();
MethodInfo Show1 = type.GetMethod("Show1");
object oResutl1 = Show1.Invoke(objTet, new object[] {
});
object oResutl = Show1.Invoke(objTet, new object[0]);
MethodInfo Show2 = type.GetMethod("Show2");
object oResutl2 = Show2.Invoke(objTet, new object[] {
123 });
//Console.WriteLine("*********************Reflection调用普重载方法*************************");
MethodInfo Show33 = type.GetMethod("Show3",new Type[] {
typeof(DateTime)});
object oResutl33 = Show33.Invoke(objTet, new object[] {
DateTime.Now });
Console.WriteLine($"{ typeof(DateTime) }>>>>>oResutl33执行完的参数值{oResutl33}");
MethodInfo Show3 = type.GetMethod("Show3", new Type[] {
typeof(int), typeof(string) });
object oResutl3 = Show3.Invoke(objTet, new object[] {
123, "阳光下的微笑" });
MethodInfo Show3_1 = type.GetMethod("Show3", new Type[] {
typeof(string), typeof(int) });
object oResutl3_1 = Show3_1.Invoke(objTet, new object[] {
"明日梦", 234 });
MethodInfo Show3_2 = type.GetMethod("Show3", new Type[] {
typeof(int) });
object oResutl3_2 = Show3_2.Invoke(objTet, new object[] {
345 });
MethodInfo Show3_3 = type.GetMethod("Show3", new Type[] {
typeof(string) });
object oResutl3_3 = Show3_3.Invoke(objTet, new object[] {
"赤" });
MethodInfo Show3_4 = type.GetMethod("Show3", new Type[0]);
object oResutl3_4 = Show3_4.Invoke(objTet, new object[] {
});
Console.WriteLine("*********************Reflection调用私有方法*************************");
MethodInfo Show4 = type.GetMethod("Show4", BindingFlags.NonPublic | BindingFlags.Instance);
object oResutl4 = Show4.Invoke(objTet, new object[] {
"伟文" });
MethodInfo Show5 = type.GetMethod("Show5", BindingFlags.Static | BindingFlags.Public);
object oResutl5 = Show5.Invoke(objTet, new object[] {
"追逐梦想的人。。" });
object oResutl5_1 = Show5.Invoke(null, new object[] {
"you。。" });
}
5.リフレクティブコールジェネリッククラス+ジェネリックメソッド
Console.WriteLine("*********************Reflections实例化泛型类+调用泛型方法*************************");
{
GenericMethod genericMethod = new GenericMethod();
genericMethod.Show<int, string, DateTime>(123, "黄大仙", DateTime.Now);
Assembly assembly3 = Assembly.LoadFrom("HomeWork.SqlHelper.dll"); //dll名称(需要后缀)
Type type = assembly3.GetType("HomeWork.SqlHelper.GenericMethod");
object genericTest = Activator.CreateInstance(type);
MethodInfo show = type.GetMethod("Show");
//注意:需要指定泛型方法的泛型类型
MethodInfo show1 = show.MakeGenericMethod(new Type[] {
typeof(int), typeof(string), typeof(DateTime) });
show1.Invoke(genericTest, new object[] {
123, "黄大仙", DateTime.Now });//如果是泛型方法,需要先确定类型,再执行方法,注意:指定的类型和传入的参数类型必须匹配
}
//泛型类
{
Assembly assembly3 = Assembly.LoadFrom("HomeWork.SqlHelper.dll"); //dll名称(需要后缀)
Console.WriteLine(typeof(GenericClass<,,>));
//下面的方法未能成功获取到原因由于它是泛型类。要在声明类的时候就告知参数类型
//Type type = assembly3.GetType("HomeWork.SqlHelper.GenericClass`3");
//MethodInfo show = type.GetMethod("Show");
//MethodInfo show2 = show.MakeGenericMethod(new Type[] { typeof(DateTime), typeof(int), typeof(string) });
Type type = assembly3.GetType("HomeWork.SqlHelper.GenericClass`3");
Type type1 = type.MakeGenericType(new Type[] {
typeof(int), typeof(string), typeof(DateTime) });
object genericObj = Activator.CreateInstance(type1);
MethodInfo show1 = type1.GetMethod("Show");
show1.Invoke(genericObj, new object[] {
234, "工程师 冯", DateTime.Now });
//GenericClass genericClass = new DB.SqlServer.GenericClass();
GenericClass<int, string, DateTime> genericClass = new GenericClass<int, string, DateTime>();
genericClass.Show(234, "工程师 冯", DateTime.Now);
}
6.リフレクションパフォーマンスの問題
- Stopwatchを使用して、動的ライブラリを取得してからインスタンスプロセスに到達するまでに必要な時間を監視できます。ループすることでテストできます。
- テスト後、リフレクションがパフォーマンスの問題を引き起こすことが実際にわかりました。ただし、動的ライブラリを取得してオブジェクトを作成するには時間がかかります。
- しかし、それは多くのサイクルの場合です。これは、コードの最適化によって回避できます。といった。ループ内にそれほど多くのオブジェクトを取得することはまったくありません。取得オブジェクトをループの外側に配置するだけです。
- このようにして、速度差を無視できます。
先生が話した利点のいくつか
//デカップリング:詳細への依存を取り除く
//あなたの会社が新しいテクニカルマネージャーに来た場合;それを行うためにMySql
//リフレクションに従事したいと言う
//1.MySqlHelperを実装するだけでよい
/ / 2.Dllファイルをコピーします
// 3。構成ファイルを
変更します
//データベースのバージョンを変更します//プログラムの構成可能性を実現します;プログラム拡張;
//反射はシングルトンを破壊します//反射
はメソッドの権限を突破できます制限;
7.フレームでの反射の適用
反射:IOC
反射应用于哪些框架;
IOC框架;反射+配置文件+工厂==IOC框架中应用;
反射--MVC
dll: HomeWork.SqlHelper.dll
type: HomeWork.SqlHelper.GenericDouble
就可以创建对象
type可以获取到Method===Method名称--字符串
dll名称+类名称+方法名称===可以调用这个方法
localhost://Home/Index/123== 可以调用到MVC项目中的某一个Action,你们觉得这是用的什么技术?
MVC中调用方法就是反射的真实写照。。
反射在ORM中的应用:
ORM---对象关系映射,就是通过对类的达成对数据库的操作;
方法、属性、字段
8.ORMデータベースアクセスをカプセル化します
//控制台程序
{
SqlServerHelper sqlServerHelper = new SqlServerHelper();
//Company company = sqlServerHelper.QueryCompany(1);
Company company = sqlServerHelper.Find<Company>(1);
User user = sqlServerHelper.Find<User>(1);
Console.WriteLine(company);
Console.WriteLine(user);
}
//SqlServerHelper中的方法,通过反射结合泛型就能实现数据的查询。经过小扩展可以实现删除与添加数据。
public T Find<T>(int id) where T : BaseModel
{
string constr = "server=.;database=CustomerDB;uid=sa;pwd=sasa";
Type type = typeof(T);
object oResult = Activator.CreateInstance(type);
var propList = type.GetProperties().Select(p => $"[{p.Name}]");
string props = string.Join(",", propList);
string sql = $"select {props} from [{type.Name}] where id={id}";
using (SqlConnection con = new SqlConnection(constr)) {
using (SqlCommand command=new SqlCommand())
{
command.Connection = con;
command.CommandText = sql;
con.Open();
SqlDataReader reader = command.ExecuteReader();
if (reader.Read())
{
foreach (PropertyInfo prop in type.GetProperties())
{
prop.SetValue(oResult, reader[prop.Name]);
}
}
}
}
return oResult as T;
}