18.Unity和ILR互相调用反射

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热更工程中内容:

  1. IType type = appdomain.LoadedTypes["TypeName"]; Type t = type.ReflectedType;
  2. 不能使用 Activator.CreateInstancenew T() 创建实例,只能通过Lesson3中的反射方式创建:appdomain.Instantiate 或者 type.GetConstructorInvoke

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中内容,我们需要怎么做?

  1. 通过appDomain中的LoadedTypes字典获取到对应类的IType

  2. 再通过IType对象中的ReflectionType成员获取到Type对象

  3. 使用Type相关反射知识处理即可



转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏