目次
I. 概要
リフレクションとは、プログラムが自身の状態や動作にアクセス、検出、および変更する機能を指します。
アセンブリにはモジュールが含まれ、モジュールには型が含まれ、型にはメンバーが含まれます。リフレクションは、アセンブリ、モジュール、および型をカプセル化するオブジェクトを提供します。
リフレクションを使用すると、型のインスタンスを動的に作成したり、型を既存のオブジェクトにバインドしたり、既存のオブジェクトから型を取得したりできます。その後、その型のメソッドを呼び出したり、そのフィールドやプロパティにアクセスしたりできます。
アドバンテージ:
1. リフレクションにより、プログラムの柔軟性と拡張性が向上します。
2. カップリングを軽減し、自己適応能力を向上させます。
3. これにより、プログラムはターゲット クラスを事前にハードコーディングすることなく、任意のクラスのオブジェクトを作成および制御できます。
欠点:
1. パフォーマンスの問題: リフレクションの使用は基本的に解釈操作であり、フィールドやメソッドへのアクセスに使用した場合、直接コードよりもはるかに遅くなります。したがって、リフレクション メカニズムは主に、高い柔軟性と拡張性が必要なシステム フレームワークで使用され、通常のプログラムには推奨されません。
2. リフレクションを使用すると、プログラムの内部ロジックが曖昧になります。プログラマはソース コードでプログラムのロジックを確認したいと考えますが、リフレクションはソース コードのテクノロジをバイパスするため、メンテナンス上の問題が発生し、リフレクション コードは対応する直接コードよりも複雑です。
リフレクションには次のような用途があります。
実行時に属性情報を表示できます。
これにより、コレクション内のさまざまな型を検査したり、それらの型をインスタンス化したりできます。
メソッドとプロパティ (プロパティ) の遅延バインディングが可能になります。
これにより、実行時に新しいタイプを作成し、これらのタイプを使用していくつかのタスクを実行できます。
次に、クラスをインスタンス化します。
リフレクションを使用してクラスをインスタンス化したい場合は、Activator.CreateInstance メソッドを使用できますが、実際には、C# のリフレクションのパフォーマンスは新しいものよりもはるかに悪いため、一般にリフレクションは推奨されませんが、それが意味するわけではありません。多くのプロジェクトでは、リフレクションの頻度も非常に高くなります。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ReflectionTest
{
internal class Program
{
static void Main(string[] args)
{
Type type = typeof(MyClass);
object obj = Activator.CreateInstance(type);
MyClass myClass = (MyClass)obj;
Console.WriteLine("年龄:{0}", myClass.Age);
Console.ReadKey();
}
}
public class MyClass
{
public int Age { get; set; } = 12;
}
}
走る:
3. リフレクションの割り当て
1. フィールドの種類
FieldInfo.SetValue を使用してフィールドに値を割り当てることができます
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ReflectionTest
{
internal class Program
{
static void Main(string[] args)
{
Type type = typeof(MyClass);
object obj = Activator.CreateInstance(type);
FieldInfo field = type.GetField("Age");
if (field != null)
field.SetValue(obj, 42);
MyClass myClass = (MyClass)obj;
Console.WriteLine("年龄:{0}", myClass.Age);
Console.ReadKey();
}
}
public class MyClass
{
public int Age = 12;
}
}
走る:
2. 属性の種類
前のセクションのコードによると、フィールド Age の属性を削除したことがわかります。フィールドが属性の場合、type.GetField("フィールド名") メソッドを呼び出すと null が返されます。
属性に値を割り当てる方法は次のとおりです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ReflectionTest
{
internal class Program
{
static void Main(string[] args)
{
Type type = typeof(MyClass);
object obj = Activator.CreateInstance(type);
PropertyInfo property = type.GetProperty("UserName");
property.SetValue(obj, "李四");
MyClass myClass = (MyClass)obj;
Console.WriteLine("用户名:{0}", myClass.UserName);
Console.ReadKey();
}
}
public class MyClass
{
public int Age = 12;
public string UserName { get; set; } = "张三";
}
}
走る:
4 番目に、フィールド値を取得します
フィールドの値を取得するには、現在のクラスのエンティティ オブジェクトを取得するだけで済みます。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ReflectionTest
{
internal class Program
{
static void Main(string[] args)
{
Type type = typeof(MyClass);
object obj = Activator.CreateInstance(type);
MyClass myClass = (MyClass)obj;
Console.WriteLine("年龄:{0}", myClass.Age);
Console.WriteLine("用户名:{0}", myClass.UserName);
Console.ReadKey();
}
}
public class MyClass
{
public int Age = 12;
public string UserName { get; set; } = "张三";
}
}
走る:
5. フィールド名を取得する
1. フィールドの種類
以下のメソッドを使用するとすべてのフィールド名を取得できますが、この書き方では属性のフィールド名は取得できません。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ReflectionTest
{
internal class Program
{
static void Main(string[] args)
{
Type type = typeof(MyClass);
FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.Instance);
foreach (FieldInfo field in fields)
{
Console.WriteLine(field.Name);
}
Console.ReadKey();
}
}
public class MyClass
{
public int Age = 12;
public string UserName { get; set; } = "张三";
}
}
走る:
2. 属性の種類
コードはほぼ同じですが、通常のフィールドは GetFields を使用し、プロパティは GetProperties を使用する点が異なります。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ReflectionTest
{
internal class Program
{
static void Main(string[] args)
{
Type type = typeof(MyClass);
PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (PropertyInfo property in properties)
{
Console.WriteLine(property.Name);
}
Console.ReadKey();
}
}
public class MyClass
{
public int Age = 12;
public string UserName { get; set; } = "张三";
}
}
走る:
6. フィールドタイプを取得する
1. フィールドの種類
FieldInfo.FieldType を使用してフィールドのタイプを取得できます。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ReflectionTest
{
internal class Program
{
static void Main(string[] args)
{
Type type = typeof(MyClass);
FieldInfo field = type.GetField("Age");
Type fieldType = field.FieldType;
Console.WriteLine(fieldType);
Console.ReadKey();
}
}
public class MyClass
{
public int Age = 12;
public string UserName { get; set; } = "张三";
}
}
走る:
2. 属性の種類
PropertyInfo.GetProperty メソッドを使用してプロパティのタイプを取得できます。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ReflectionTest
{
internal class Program
{
static void Main(string[] args)
{
Type type = typeof(MyClass);
PropertyInfo property = type.GetProperty("UserName");
Type propertyType = property.PropertyType;
Console.WriteLine(propertyType);
Console.ReadKey();
}
}
public class MyClass
{
public int Age = 12;
public string UserName { get; set; } = "张三";
}
}
走る:
7.呼び出し方法
メソッドは、MethodInfo.Invoke を使用して呼び出すことができます。
1.パラメータがあります
ここで、パラメーターは配列を使用しており、パラメーターが 2 つあると仮定すると、対応する型の 2 つの値を配列に追加する必要もあります。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ReflectionTest
{
internal class Program
{
static void Main(string[] args)
{
Type type = typeof(MyClass);
object obj = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("Test");
object[] parameters = new object[] { "老王" };
string result = (string)method.Invoke(obj, parameters);
Console.WriteLine("返回值 {0}" , result);
Console.ReadKey();
}
}
public class MyClass
{
public string Test(string name)
{
return "你的名字:" + name;
}
}
}
走る:
2.パラメータなし
メソッドにパラメータがない場合は、値を渡して空を渡します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace ReflectionTest
{
internal class Program
{
static void Main(string[] args)
{
Type type = typeof(MyClass);
object obj = Activator.CreateInstance(type);
MethodInfo method = type.GetMethod("SayHi");
method.Invoke(obj, null);
Console.ReadKey();
}
}
public class MyClass
{
public void SayHi()
{
Console.WriteLine("你好");
}
}
}
走る:
終了
この投稿が役に立った場合は、フォロー + いいね + メッセージを残してください。ありがとうございます。
終わり