voidOnHotFixLoaded() { Debug.Log("C#工程中反射是一个非常经常用到功能,ILRuntime也对反射进行了支持,在热更DLL中使用反射跟原生C#没有任何区别,故不做介绍"); Debug.Log("这个Demo主要是介绍如何在主工程中反射热更DLL中的类型"); Debug.Log("假设我们要通过反射创建HotFix_Project.InstanceClass的实例"); Debug.Log("显然我们通过Activator或者Type.GetType(\"HotFix_Project.InstanceClass\")是无法取到类型信息的"); Debug.Log("热更DLL中的类型我们均需要通过AppDomain取得"); var it = appdomain.LoadedTypes["HotFix_Project.InstanceClass"]; Debug.Log("LoadedTypes返回的是IType类型,但是我们需要获得对应的System.Type才能继续使用反射接口"); var type = it.ReflectionType; Debug.Log("取得Type之后就可以按照我们熟悉的方式来反射调用了"); var ctor = type.GetConstructor(new System.Type[0]); //var obj = System.Activator.CreateInstance(type);//NG var obj = ctor.Invoke(null); Debug.Log("打印一下结果"); Debug.Log(obj); Debug.Log("我们试一下用反射给字段赋值"); var fi = type.GetField("id", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); fi.SetValue(obj, 111111); Debug.Log("我们用反射调用属性检查刚刚的赋值"); var pi = type.GetProperty("ID"); Debug.Log("ID = " + pi.GetValue(obj, null));
if (type is ILRuntime.Reflection.ILRuntimeType) { ILRuntime.Reflection.ILRuntimeType ilt = (ILRuntime.Reflection.ILRuntimeType)type; var ilType = ilt.ILType; var gargs = ilt.GenericTypeArguments; } elseif (type is ILRuntime.Reflection.ILRuntimeWrapperType) { var clrttype = (ILRuntime.Reflection.ILRuntimeWrapperType)type; var t = clrttype.GenericTypeArguments; } }
Debug.Log("可以看到已经成功了"); Debug.Log("下面做另外一个实验"); Debug.Log("GetComponent跟AddComponent类似,需要我们自己处理"); SetupCLRRedirection2(); appdomain.Invoke("HotFix_Project.TestMonoBehaviour", "RunTest2", null, gameObject); Debug.Log("成功了"); Debug.Log("那我们怎么从Unity主工程获取热更DLL的MonoBehaviour呢?"); Debug.Log("这需要我们自己实现一个GetComponent方法"); var type = appdomain.LoadedTypes["HotFix_Project.SomeMonoBehaviour2"] as ILType; var smb = GetComponent(type); var m = type.GetMethod("Test2"); Debug.Log("现在来试试调用"); appdomain.Invoke(m, smb, null);