UH4L13——Unity反射调用ILRuntime

ILRuntime反射相关

  • Unity中反射使用ILRuntime热更工程中内容

    1. 通过IType​获取类型消息

      1
      2
      IType type = appdomain.LoadedTypes["TypeName"];
      Type t = type.ReflectedType;
    2. 不能使用Activator.CreateInstance​ 或 new T()​ 创建实例
      只能通过创建ILRuntime中对象中的反射方式创建
      appdomain.Instantiate​ 或者 type.GetConstructor​ 后 Invoke

  • ILRuntime热更工程中使用反射,和C#中使用反射一样

在热更工程中使用反射

按照反射的规则正常调用即可,和C#中反射没有任何区别

在Unity工程中调用反射热更工程内容

假设要反射调用下面的热更新工程内的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
using System.Collections.Generic;
using UnityEngine;

namespace HotFix_Project
{
public class Lesson3_Test
{
public int TestI;

private string str;

public Lesson3_Test() { }

public Lesson3_Test(string str)
{
this.str = str;
}

public string Str
{
get => str;
set => str = value;
}

public static void TestStaticFun()
{
//热更工程内可以直接调用UnityEngine命名空间内的内容
Debug.Log("无参静态方法");
}

public static int TestStaticFun2(int i)
{
Debug.Log("有参静态方法" + i);
return i + 10;
}

public void TestFun()
{
Debug.Log("无参成员方法");
}
public void TestFun(int i)
{
Debug.Log("有参重载函数1" + i);
}

public void TestFun(float f)
{
Debug.Log("有参重载函数2:" + f);
}

public int TestFun2(int i)
{
Debug.Log("有参有返回值成员方法" + i);
return i + 10;
}

public float TestFun3(int i, ref List<int> list, out float f)
{
f = 0.5f;
list.Add(5);
for (int j = 0; j < list.Count; j++)
{
Debug.Log(list[j]);
}
return i + list.Count + f;
}
}
}

我们已在创建ILRuntime中对象时接触过 Unity 反射创建 ILRuntime 中的对象,我们就使用了ILRuntime中的反射相关内容进行对象的创建

  1. 获取ILRuntime对应IType​类型

    1
    2
    3
    4
    ILRuntimeMgr.Instance.StartILRuntime(() =>
    {
    ILRuntimeMgr.Instance.appDomain.Invoke("HotFix_Project.ILRuntimeMain", "Main", null, null);
    });
  2. 通过IType获取到对应的Type

    1
    2
    3
    4
    5
    6
    ILRuntimeMgr.Instance.StartILRuntime(() =>
    {
    ILRuntimeMgr.Instance.appDomain.Invoke("HotFix_Project.ILRuntimeMain", "Main", null, null);
    IType iType = ILRuntimeMgr.Instance.appDomain.LoadedTypes["HotFix_Project.Lesson3_Test"];
    Type type = iType.ReflectionType;
    });
  3. 通过反射获取各种内容来进行调用

    1. 构造函数

      注意

      在Unity中反射使用热更工程中类时,我们不能够使用 Activator.CreateInstance(type)​ 的形式去创建对象,这样会报错
      想要在主工程中创建热更工程中的对象,必须使用我们之前将过的三种方式,详见:UH4L3——实例化ILRuntime中对象

      1
      2
      3
      4
      5
      6
      7
      8
      9
      ILRuntimeMgr.Instance.StartILRuntime(() =>
      {
      ILRuntimeMgr.Instance.appDomain.Invoke("HotFix_Project.ILRuntimeMain", "Main", null, null);
      IType iType = ILRuntimeMgr.Instance.appDomain.LoadedTypes["HotFix_Project.Lesson3_Test"];
      Type type = iType.ReflectionType;

      object obj = type.GetConstructor(new Type[0]).Invoke(null);
      print(obj);
      });
    2. 成员变量

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      ILRuntimeMgr.Instance.StartILRuntime(() =>
      {
      ILRuntimeMgr.Instance.appDomain.Invoke("HotFix_Project.ILRuntimeMain", "Main", null, null);
      IType iType = ILRuntimeMgr.Instance.appDomain.LoadedTypes["HotFix_Project.Lesson3_Test"];
      Type type = iType.ReflectionType;

      object obj = type.GetConstructor(new Type[0]).Invoke(null);
      print(obj);
      var testIInfo = type.GetField("testI");
      print(testIInfo.GetValue(obj)); //通过反射获取成员变量
      });
    3. 成员属性

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      ILRuntimeMgr.Instance.StartILRuntime(() =>
      {
      ILRuntimeMgr.Instance.appDomain.Invoke("HotFix_Project.ILRuntimeMain", "Main", null, null);
      IType iType = ILRuntimeMgr.Instance.appDomain.LoadedTypes["HotFix_Project.Lesson3_Test"];
      Type type = iType.ReflectionType;

      object obj = type.GetConstructor(new Type[0]).Invoke(null);
      print(obj);
      var testIInfo = type.GetField("testI");
      print(testIInfo.GetValue(obj)); //通过反射获取成员变量
      var strinfo = type.GetProperty("Str");
      strinfo.SetValue(obj, "897654"); //通过反射设置成员属性
      print(strinfo.GetValue(obj)); //通过反射获取成员属性
      });
    4. 成员方法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      ILRuntimeMgr.Instance.StartILRuntime(() =>
      {
      ILRuntimeMgr.Instance.appDomain.Invoke("HotFix_Project.ILRuntimeMain", "Main", null, null);
      IType iType = ILRuntimeMgr.Instance.appDomain.LoadedTypes["HotFix_Project.Lesson3_Test"];
      Type type = iType.ReflectionType;

      object obj = type.GetConstructor(new Type[0]).Invoke(null);
      print(obj);
      var testIInfo = type.GetField("TestI");
      print(testIInfo.GetValue(obj)); //通过反射获取成员变量
      var strinfo = type.GetProperty("Str");
      strinfo.SetValue(obj, "897654"); //通过反射设置成员属性
      print(strinfo.GetValue(obj)); //通过反射获取成员属性
      var methodInfo = type.GetMethod("TestFun", new Type[0]);
      methodInfo.Invoke(obj, null); //通过反射调用成员方法
      });

输出:image