C# core knowledge review - 14. Reflection (Type)

1. Reflection:

What is an assembly?
An assembly is an intermediate product compiled by a compiler for further compilation and execution.
In the WINDOWS system, it generally appears in the format of a suffix of ·d11 (library file) or ·exe (executable file).
In human terms:
an assembly is a collection of code we write. All the code we write now
will eventually be translated by the compiler into an assembly for others to use,
such as a code library file (d11) or an executable file (exe)

What is reflection?
When a program is running, it can view other assemblies or its own metadata.
 The behavior of a running program to view metadata of itself or other programs is called reflection. In
human terms: when the program is running, various information classes, functions, variables, objects, etc.
of other assemblies or its own assembly code can be obtained through reflection.
etc., instantiate them, execute them, operate them

The role of reflection
: Because reflection can obtain information after the program is compiled, it improves the scalability and flexibility of the program. 1.
Obtains all metadata when the program is running, including the characteristics of the metadata.
2. When the program is running, instantiate objects and operate Object
3, create new objects when the program is running, and use these objects to perform tasks

 Type:

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

Activator:

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

Assembly

 #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

Guess you like

Origin blog.csdn.net/qq_29296473/article/details/131653798