C#リフレクション(Reflection)の共通機能

目次

I. 概要

次に、クラスをインスタンス化します。

3. リフレクションの割り当て

4 番目に、フィールド値を取得します

5. フィールド名を取得する

6. フィールドタイプを取得する

7.呼び出し方法

終了


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("你好");
        }
    }
}

走る:

 

終了

この投稿が役に立った場合は、フォロー + いいね + メッセージを残してください。ありがとうございます。

終わり

Supongo que te gusta

Origin blog.csdn.net/qq_38693757/article/details/131005278
Recomendado
Clasificación