18.更多跨域调用-反射
18.1 知识点
复制之前的主入口调用
ILRuntimeManager.Instance.StartILRuntime(() =>
{
    // 执行ILRuntime当中的一个静态函数
    // 静态函数中,就是ILRuntime热更工程自己处理的逻辑了
    ILRuntimeManager.Instance.appDomain.Invoke("HotFix_Project.ILRuntimeMain", "Start", null, null);
});
在ILRuntime工程中使用反射
按照反射的规则正常使用即可,和C#中反射没有任何区别。
在Unity工程中反射ILRuntime工程中内容
回顾之前在ILRuntime热更工程创建的Lesson4_Test,给他加一个公共成员变量,重新生成
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace HotFix_Project
{
    class Lesson4_Test
    {
        #region 成员变量
        private string str;
        public int TestInt;
        #endregion
        #region 成员属性
        public string Str
        {
            get
            {
                return str;
            }
            set
            {
                str = value;
            }
        }
        #endregion
        #region 构造函数
        public Lesson4_Test()
        {
        }
        public Lesson4_Test(string str)
        {
            this.str = str;
        }
        #endregion
        #region 静态方法
        public static void TestStaticFun()
        {
            Debug.Log("无参静态方法");
        }
        public static int TestStaticFun2(int i)
        {
            Debug.Log("有参静态方法" + i);
            return i + 10;
        }
        #endregion
        #region 成员方法
        public void TestFun()
        {
            Debug.Log("无参无返回值 成员方法调用");
        }
        public int TestFun2(int i)
        {
            Debug.Log("有参有返回值 成员方法调用");
            return 10 + i;
        }
        #endregion
        #region 重载方法
        public void TestFun(int i)
        {
            Debug.Log("重载函数1,传进来的参数是" + i);
        }
        public void TestFun(float f)
        {
            Debug.Log("重载函数2,传进来的参数是" + f);
        }
        #endregion
        #region ref和out方法
        public float TestFun3(int i, ref List<int> list, out float f)
        {
            f = .5f;
            list.Add(5);
            for (int j = 0; j < list.Count; j++)
                Debug.Log(list[j]);
            return i + list.Count + f;
        }
        #endregion
    }
}
在Unity工程得到反射类使用成员
我们已在Lesson4_Test创建对象时接触过 IType Unity反射创建ILRuntime中的对象。
我们就使用了ILRuntime中的反射相关内容进行对象的创建。
获取ILRuntime对应 IType 类型:
IType iType = ILRuntimeManager.Instance.appDomain.LoadedTypes["HotFix_Project.Lesson4_Test"];
通过 IType 获取到对应的 Type:
Type type = iType.ReflectionType;
通过反射获取各种内容来进行调用:
- 构造函数
object obj = type.GetConstructor(new Type[0]).Invoke(null);
print(obj); // HotFix_Project.Lesson4_Test
- 成员变量
var testIInfo = type.GetField("TestInt");
print(testIInfo.GetValue(obj)); // 0
- 成员属性
var strInfo = type.GetProperty("Str");
strInfo.SetValue(obj, "897654");
print(strInfo.GetValue(obj)); // 897654
- 成员方法
var methodInfo = type.GetMethod("TestFun", new Type[0]);
methodInfo.Invoke(obj, null); // 无参无返回值 成员方法调用
注意:
在Unity中反射使用ILRuntime热更工程中类时,我们不能够使用 Activator.CreateInstance(type) 的形式去创建对象,这样会报错。想要在主工程中创建ILRuntime热更工程中的对象,必须使用我们之前间接过的三种方式。
总结
Unity中反射使用ILRuntimeILRuntime热更工程中内容:
- IType type = appdomain.LoadedTypes["TypeName"]; Type t = type.ReflectedType;
- 不能使用 Activator.CreateInstance或new T()创建实例,只能通过Lesson3中的反射方式创建:appdomain.Instantiate或者type.GetConstructor后Invoke。
ILRuntimeILRuntime热更工程中使用反射,和C#中使用反射一样。
18.2 知识点代码
Lesson4_Test
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace HotFix_Project
{
    class Lesson4_Test
    {
        #region 成员变量
        private string str;
        public int TestInt;
        #endregion
        #region 成员属性
        public string Str
        {
            get
            {
                return str;
            }
            set
            {
                str = value;
            }
        }
        #endregion
        #region 构造函数
        public Lesson4_Test()
        {
        }
        public Lesson4_Test(string str)
        {
            this.str = str;
        }
        #endregion
        #region 静态方法
        public static void TestStaticFun()
        {
            Debug.Log("无参静态方法");
        }
        public static int TestStaticFun2(int i)
        {
            Debug.Log("有参静态方法" + i);
            return i + 10;
        }
        #endregion
        #region 成员方法
        public void TestFun()
        {
            Debug.Log("无参无返回值 成员方法调用");
        }
        public int TestFun2(int i)
        {
            Debug.Log("有参有返回值 成员方法调用");
            return 10 + i;
        }
        #endregion
        #region 重载方法
        public void TestFun(int i)
        {
            Debug.Log("重载函数1,传进来的参数是" + i);
        }
        public void TestFun(float f)
        {
            Debug.Log("重载函数2,传进来的参数是" + f);
        }
        #endregion
        #region ref和out方法
        public float TestFun3(int i, ref List<int> list, out float f)
        {
            f = .5f;
            list.Add(5);
            for (int j = 0; j < list.Count; j++)
                Debug.Log(list[j]);
            return i + list.Count + f;
        }
        #endregion
    }
}
Lesson18_更多跨域调用_反射
using ILRuntime.CLR.TypeSystem;
using System;
using System.Collections;
using System.Collections.Generic;
using BaseFramework;
using UnityEngine;
public class Lesson18_更多跨域调用_反射 : MonoBehaviour
{
    void Start()
    {
        #region 复制之前的主入口调用
        ILRuntimeManager.Instance.StartILRuntime(() =>
        {
            //执行ILRuntime当中的一个静态函数
            //静态函数中 就是ILRuntime热更工程自己处理的逻辑了
            ILRuntimeManager.Instance.appDomain.Invoke("HotFix_Project.ILRuntimeMain", "Start", null, null);
            #region 知识点一 在ILRuntime热更工程中使用反射
            //按照反射的规则正常使用即可
            //和C#中反射没有任何区别
            #endregion
            #region 知识点二 在Unity工程中反射ILRuntime热更工程中内容
            //我们已在Lesson4_Test创建对象时接触过 IType Unity反射创建ILRuntime中的对象
            //我们就使用了ILRuntime中的反射相关内容进行对象的创建
            
            //1.获取ILRuntime对应IType类型
            IType iType = ILRuntimeManager.Instance.appDomain.LoadedTypes["HotFix_Project.Lesson4_Test"];
            
            //2.通过IType获取到对应的Type
            Type type = iType.ReflectionType;
            
            //3.通过反射获取各种内容来进行调用
            
            //3-1构造函数
            object obj = type.GetConstructor(new Type[0]).Invoke(null);
            print(obj);//HotFix_Project.Lesson4_Test
            
            //3-2成员变量
            var testIInfo = type.GetField("TestInt");
            print(testIInfo.GetValue(obj));//0
            
            //3-3成员属性
            var strInfo = type.GetProperty("Str");
            strInfo.SetValue(obj, "897654");
            print(strInfo.GetValue(obj));//897654
            
            //3-4成员方法
            var methodInfo = type.GetMethod("TestFun", new Type[0]);
            methodInfo.Invoke(obj, null);//无参无返回值 成员方法调用
            
            
            //注意:
            //在Unity中反射使用ILRuntime热更工程中类时
            //我们不能够使用
            //Activator.CreateInstance(type)
            //的形式去创建对象
            //这样会报错
            //想要在主工程中创建ILRuntime热更工程中的对象
            //必须使用我们之前间接过的三种方式
            #endregion
            #region 总结
            //Unity中反射使用ILRuntimeILRuntime热更工程中内容
            //1.IType type = appdomain.LoadedTypes["TypeName"];
            //  Type t = type.ReflectedType;
            //2.不能使用Activator.CreateInstance 或 new T() 创建实例
            //  只能通过Lesson3中的反射方式创建
            //  appdomain.Instantiate 或者
            //  type.GetConstructor 后 Invoke
            //ILRuntimeILRuntime热更工程中使用反射
            //和C#中使用反射一样
            #endregion
        });
        #endregion
    }
}
18.3 练习题
在Unity中反射调用ILRuntime中内容,我们需要怎么做?
- 通过appDomain中的LoadedTypes字典获取到对应类的IType 
- 再通过IType对象中的ReflectionType成员获取到Type对象 
- 使用Type相关反射知识处理即可 
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com
 
            