C# のコア知識の復習 - 14. リフレクション (型)

1. 反省:

アセンブリとは何ですか?
アセンブリとは、さらにコンパイルおよび実行するためにコンパイラによってコンパイルされた中間生成物であり、
WINDOWS システムでは、通常、拡張子が ·d11 (ライブラリ ファイル) または ·exe (実行可能ファイル) の形式で表示されます。
人間の言葉で言えば、
アセンブリとは、私たちが書くコードの集合です。私たちが今書いているすべてのコードは、最終的には、コード ライブラリ ファイル (d11) や実行可能ファイル (exe) など、
他の人が使用できるようにコンパイラによってアセンブリに変換されます。
)

リフレクションとは何ですか?
プログラムの実行中に、他のアセンブリまたは独自のメタデータを表示できます。
 実行中のプログラムがそれ自身または他のプログラムのメタデータを表示する動作はリフレクションと呼ばれます。
人間の言葉で言えば、プログラムの実行中に、他のアセンブリまたはその独自のアセンブリ コードのさまざまな情報クラス、関数、変数、オブジェクトなどが表示
される可能性があります。リフレクション
などで取得したものをインスタンス化し、実行し、操作する

リフレクションの役割
: リフレクションはプログラムのコンパイル後に情報を取得できるため、プログラムの拡張性と柔軟性が向上します 1. プログラム
実行時にメタデータの特性を含むすべてのメタデータを取得します
2. プログラム実行時に実行中、オブジェクトをインスタンス化し、オブジェクト
3 を操作します。プログラムの実行中に新しいオブジェクトを作成し、これらのオブジェクトを使用してタスクを実行します。

 タイプ:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;

public class test : MonoBehaviour
{
    private void Start()
    {
        #region Type
        //Type(类的信息类)
        //它是反射功能的基础!
        //它是访问元数据的主要方式。
        //使用Type的成员获取有关类型声明的信息
        //有关类型的成员(如构造函数、方法、字段、属性和类的事件)

        #region 获取Type
        //1.万物之父object中的Get Type()可以获取对象的Type
        int a = 42;
        Type type = a.GetType();

        //2.通过type of关键字传入类名也可以得到对象的Type
        Type type1 = typeof(int);

        //3.通过类的名字也可以获取类型
        //注意类名必须包含命名空间不然找不到
        Type type2 = Type.GetType("System.Int32");
        #endregion

        #region 获取类程序集信息
        Debug.Log(type1.Assembly);
        #endregion

        #region 获取类所有公共成员
        //获取Type
        Type t = typeof(Test);
        //得到公共成员
        //需要引用命名空间using System.Reflection;
        MemberInfo[] info = t.GetMembers();
        for (int i = 0; i < info.Length; i++)
        {
            Debug.Log(info[i]);
        }
        #endregion

        #region 获取类的公共构造函数并调用
        // 1.获取所有构造函数
        ConstructorInfo[] constructors = t.GetConstructors();
        for (int i = 0; i < constructors.Length; i++)
        {
            Debug.Log(constructors[i]);
        }
        // 2.获取其中一个构造函数并执行
        //得构造函数传入 Type数组 数组中内容按顺序是参数类型
        //执行构造函数传入 object 数组表示按顺序传入的参数        
        // 2 - 1得到无参构造
        ConstructorInfo cons = t.GetConstructor(new Type[0]);
        //执行无参构造
        Test obj = cons.Invoke(null) as Test;
        // 2 - 2得到有参构造
        ConstructorInfo cons2 = t.GetConstructor(new Type[] { typeof(int), typeof(string) });
        obj = cons2.Invoke(new object[] { 4, "454" }) as Test;
        Debug.Log(obj.str);
        #endregion

        #region 获取类的公共成员变量
        // 1.得到所有成员变量
        FieldInfo[] fieldInfos = t.GetFields();
        for (int i = 0; i < fieldInfos.Length; i++)
        {
            Debug.Log(fieldInfos[i]);
        }
        // 2.得到指定名称的公共成员变量
        FieldInfo infoJ = t.GetField("j");
        Debug.Log(infoJ);
        // 3.通过反射获取和设置对象的值
        Test test = new Test();
        test.j = 1;   
        //3-1通过反射获取对象的某个变量的值
        Debug.Log(infoJ.GetValue(test));
        //3-2通过反射设置指定对象的某个变量的值
        infoJ.SetValue(test, 100);
        Debug.Log(infoJ.GetValue(test));
        #endregion

        #region 获取类的公共成员方法
        //通过Type类中的Get Method方法得到类中的方法
        //Method Info是方法的反射信息
        Type strtype = typeof(string);
        //1.如果存在方法重载用Type数组表示参数类型
        MethodInfo[] methods = strtype.GetMethods();
        for (int i = 0; i < methods.Length; i++)
        {
            Debug.Log(methods[i]);
        }
        MethodInfo substr = strtype.GetMethod("Substring",new Type[] {typeof(int),typeof(int)});
        // 2.调用该方法
        //注意:如果是静态方法Invoke中的第一个参数传nul1即可
        string str = "absgfdghz";
        object oobbjj = substr.Invoke(str, new object[] { 7, 2 });
        Debug.Log(oobbjj);
        #endregion


        #endregion
    }

}

class Test
{
    private int i = 0;

    public int j = 0;

    public string str = "122";

    public Test() { }

    public Test(int i) { this.i = i; }

    public Test(int i,string str) { this.str = str; }

    public void Speak() { Debug.Log("000"); }
}

活性剤:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;

public class test : MonoBehaviour
{
    private void Start()
    {
        #region Activator
        // 用于快速实例化对象的类
        //用于将Type对象快捷实例化为对象
        //先得到Type
        //然后快速实例化一个对象
        Type testType = typeof(Test);
        //1.无参构造
        Test testobj = Activator.CreateInstance(testType) as Test;
        //2.有参数构造
        testobj = Activator.CreateInstance(testType,99) as Test;

        testobj = Activator.CreateInstance(testType, 99,"451") as Test;
        #endregion
        
    }

}

class Test
{
    private int i = 0;

    public int j = 0;

    public string str = "122";

    public Test() { }

    public Test(int i) { this.i = i; }

    public Test(int i,string str) { this.str = str; }

    public void Speak() { Debug.Log("000"); }
}

組立

 #region Assembly
        //程序集类
        //主要用来加载其它程序集,加载后才能用Type来使用其它程序集中的信息
        //如果想要使用不是自己程序集中的内容需要先加载程序集
        //比如d11文件(库文件)
        //简单的把库文件看成一种代码仓库,它提供给使用者一些可以直接拿来用的变量、函数或类

        //三种加载程序集的函数
        //一般用来加载在同一文件下的其它程序集
        //Assembly as em bly2=Assembly.Load("程序集名称");

        //一般用来加载不在同一文件下的其它程序集
        //Assembly as em bly=Assembly.Load From("包含程序集清单的文件的名称或路径");
        //Assembly as em bly3=Assembly.Load File"要加载的文件的完全限定路径");

        //1.先加载一个指定程序集
        Assembly asembly = Assembly.LoadFrom(@"H:\Feng\UnityProject\C#\类库测试\类库测试\bin\Debug\类库测试.dll");
        Type[] types = asembly.GetTypes();
        for (int i = 0; i < types.Length; i++)
        {
            Debug.Log(types[i]);
        }
        //2.再加载程序集中的一个类对象之后才能使用反射
        Type icon = asembly.GetType("类库测试.Feng");
        MemberInfo[] menbers = icon.GetMembers();
        for (int i = 0; i < menbers.Length; i++)
        {
            Debug.Log(menbers[i]);
        }
        //通过反射实例化对象

        // !!!!!!!!!!!!!!  这里是示意  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        Type movedir = asembly.GetType("类库测试.Feng");
        FieldInfo right = movedir.GetField("Right");
        //实例化对象
        object iconobj = Activator.CreateInstance(icon);
        //通过反射得到对象的方法
        MethodInfo move = icon.GetMethod("Move");

        move.Invoke(iconobj, null);

        //3.类库工程创建
        #endregion

おすすめ

転載: blog.csdn.net/qq_29296473/article/details/131653798