4.Unity调用ILRuntime-实例化对象
4.1 知识点
在ILRuntime热更工程中新建一个类,给类并添加两个构造函数
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HotFix_Project
{
class Lesson4_Test
{
public string str;
public Lesson4_Test()
{
}
public Lesson4_Test(string str)
{
this.str = str;
}
}
}
在Unity中跨域调用ILRuntime中的类
需要让ILRuntime重新生成最新的dll和pdb文件,右键重新生成热更工程,这样会更新StreamAsset下的dll文件和pdb文件
AppDomain.Instantiate 实例化ILRuntime中的对象
AppDomain.LoadedTypes 得到ILRuntime中的对象的IType
ITyp.Instantiate 实例化ILRuntime中的对象
IType.ReflectionType.GetConstructor.Invoke 实例化ILRuntime中的对象
//需要让ILRuntime重新生成最新的dll和pdb文件
ILRuntimeManager.Instance.StartILRuntime(() =>
{
//这里面做的事情 是在加载完了dll和pdb文件后做的
// 得到appDomain单例
ILRuntime.Runtime.Enviorment.AppDomain appDomain = ILRuntimeManager.Instance.appDomain;
//AppDomain.Instantiate 传入HotFix_Project.类名实例化对象
//方式一:appdomain中的Instantiate方法
// 参数一:类的命名空间.类名
// 参数二:参数列表
object obj = appDomain.Instantiate("HotFix_Project.Lesson4_Test");
// 注意我们是不能用Lesson4_Test来装返回的对象的 因为ILRuntime底层用自定义的类表示热更的类 实例化的类其实不是Lesson4_Test了
print(obj);//HotFix_Project.Lesson4_Test
// 有参构造,传入object数组,数组元素作为参数
obj = appDomain.Instantiate("HotFix_Project.Lesson4_Test", new object[] { "123" });
print(obj);//HotFix_Project.Lesson4_Test
//AppDomain.LoadedTypes字典 传入HotFix_Project.类名作为键得到IType值进行实例化
//方式二:appdomain中LoadedTypes字典获取IType类型后,强转为ILType后调用Instantiate方法
// 该方式类似反射
IType type = appDomain.LoadedTypes["HotFix_Project.Lesson4_Test"];
//IType强转成ILType再进行Instantiate实例化
obj = ((ILType)type).Instantiate();
print(obj);//HotFix_Project.Lesson4_Test
// 有参构造,传入object数组,数组元素作为参数
obj = ((ILType)type).Instantiate(new object[] { "234" });
print(obj);//HotFix_Project.Lesson4_Test
//IType.ReflectionType.GetConstructor 得到IType的构造函数信息进行实例化
//方式三:通过方式二中得到的IType对象,再去得到它的构造函数进行实例化
// 该方式类似反射
ConstructorInfo info = type.ReflectionType.GetConstructor(new Type[0]);
//info.Invoke 无参不用传参
obj = info.Invoke(null);
print(obj);//HotFix_Project.Lesson4_Test
// 传入object数组得到有参构造函数信息
info = type.ReflectionType.GetConstructor(new Type[] { typeof(string) });
// 使用有参构造,传入object数组,数组元素作为参数
obj = info.Invoke(new object[] { "11111" });
print(obj);//HotFix_Project.Lesson4_Test
//综合来说,更推荐方式2,因为之后在调用对象方法变量时,通过方式2更方便
});
总结
Unity中实例化ILRuntime中类对象主要有三种方式
- appdomain中的Instantiate方法
- appdomain中LoadedTypes字典获取IType类型后, 强转为ILType后调用Instantiate方法
- appdomain中LoadedTypes字典获取IType类型后, 再去获取它的构造函数信息用于实例化对象
推荐使用方式2或者3,因为他们都需要先获取IType,之后调用对象中成员时更方便
4.2 知识点代码
Lesson4_Test
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HotFix_Project
{
class Lesson4_Test
{
public string str;
public Lesson4_Test()
{
}
public Lesson4_Test(string str)
{
this.str = str;
}
}
}
Lesson04_Unity调用ILRuntime_实例化对象
using ILRuntime.CLR.TypeSystem;
using ILRuntime.Runtime.Enviorment;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using BaseFramework;
using UnityEngine;
public class Lesson04_Unity调用ILRuntime_实例化对象 : MonoBehaviour
{
void Start()
{
#region 知识点一 在ILRuntime热更工程中新建一个类
//只需要在ILRuntime的工程中新建一个类即可
//并为该类声明几个构造函数重载
#endregion
#region 知识点二 在Unity中跨域调用ILRuntime中的类
//需要让ILRuntime重新生成最新的dll和pdb文件
ILRuntimeManager.Instance.StartILRuntime(() =>
{
//这里面做的事情 是在加载完了dll和pdb文件后做的
// 得到appDomain单例
ILRuntime.Runtime.Enviorment.AppDomain appDomain = ILRuntimeManager.Instance.appDomain;
//AppDomain.Instantiate 传入HotFix_Project.类名实例化对象
//方式一:appdomain中的Instantiate方法
// 参数一:类的命名空间.类名
// 参数二:参数列表
object obj = appDomain.Instantiate("HotFix_Project.Lesson4_Test");
// 注意我们是不能用Lesson4_Test来装返回的对象的 因为ILRuntime底层用自定义的类表示热更的类 实例化的类其实不是Lesson4_Test了
print(obj);//HotFix_Project.Lesson4_Test
// 有参构造,传入object数组,数组元素作为参数
obj = appDomain.Instantiate("HotFix_Project.Lesson4_Test", new object[] { "123" });
print(obj);//HotFix_Project.Lesson4_Test
//AppDomain.LoadedTypes字典 传入HotFix_Project.类名作为键得到IType值进行实例化
//方式二:appdomain中LoadedTypes字典获取IType类型后,强转为ILType后调用Instantiate方法
// 该方式类似反射
IType type = appDomain.LoadedTypes["HotFix_Project.Lesson4_Test"];
//IType强转成ILType再进行Instantiate实例化
obj = ((ILType)type).Instantiate();
print(obj);//HotFix_Project.Lesson4_Test
// 有参构造,传入object数组,数组元素作为参数
obj = ((ILType)type).Instantiate(new object[] { "234" });
print(obj);//HotFix_Project.Lesson4_Test
//IType.ReflectionType.GetConstructor 得到IType的构造函数信息进行实例化
//方式三:通过方式二中得到的IType对象,再去得到它的构造函数进行实例化
// 该方式类似反射
ConstructorInfo info = type.ReflectionType.GetConstructor(new Type[0]);
//info.Invoke 无参不用传参
obj = info.Invoke(null);
print(obj);//HotFix_Project.Lesson4_Test
// 传入object数组得到有参构造函数信息
info = type.ReflectionType.GetConstructor(new Type[] { typeof(string) });
// 使用有参构造,传入object数组,数组元素作为参数
obj = info.Invoke(new object[] { "11111" });
print(obj);//HotFix_Project.Lesson4_Test
//综合来说,更推荐方式2,因为之后在调用对象方法变量时,通过方式2更方便
});
#endregion
#region 总结
//Unity中实例化ILRuntime中类对象主要有三种方式
//1.appdomain中的Instantiate方法
//2.appdomain中LoadedTypes字典获取IType类型后, 强转为ILType后调用Instantiate方法
//3.appdomain中LoadedTypes字典获取IType类型后, 再去获取它的构造函数信息用于实例化对象
//推荐使用方式2或者3,因为他们都需要先获取IType,之后调用对象中成员时更方便
#endregion
}
}
4.3 练习题
练习一下Unity跨域实例化ILRuntime中的类对象
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com