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