/// <summary> /// Active /// </summary> /// <param name="classData"></param> public void Active(ClassData classData) { string classType = $"{classData.classNamespace + (classData.classNamespace == "" ? "" : ".")}{classData.className}"; IType type = InitJEngine.Appdomain.LoadedTypes[classType]; Type t = type.ReflectionType; //获取实际属性 //这边获取clrInstance的基类,这样可以获取不同适配器 var clrInstance = gameObject.GetComponents <CrossBindingAdaptorType>() .Last(clr => clr.ILInstance.Type == type as ILType); //是否激活 if (classData.activeAfter) { if (classData.BoundData == false && classData.requireBindFields && classData.fields.Count > 0) { Log.PrintError($"自动绑定{name}出错:{classType}没有成功绑定数据,自动激活成功,但可能会抛出空异常!"); } //Mono类型能设置enabled if (clrInstance.GetType().IsSubclassOf(typeof(MonoBehaviour))) { ((MonoBehaviour)clrInstance).enabled = true; } //不管是啥类型,直接invoke这个awake方法 var awakeMethod = clrInstance.GetType().GetMethod("Awake", BindingFlags.Default | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Static); if (awakeMethod == null) { awakeMethod = t.GetMethod("Awake", BindingFlags.Default | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Static); } else { awakeMethod.Invoke(clrInstance, null); classData.Activated = true; } if (awakeMethod == null) { Log.PrintError($"{t.FullName}不包含Awake方法,无法激活,已跳过"); } else if (!classData.Activated) { awakeMethod.Invoke(t, null); } classData.Activated = true; } Remove(); }
/// <summary> /// Active /// </summary> /// <param name="classData"></param> public void Active(ClassData classData) { string classType = $"{classData.classNamespace + (classData.classNamespace == "" ? "" : ".")}{classData.className}"; Type t = classData.ClassType; //获取实际属性 var clrInstance = classData.ClrInstance; //是否激活 if (classData.activeAfter) { if (classData.BoundData == false && classData.fields != null && classData.fields.Count > 0) { Log.PrintError($"自动绑定{name}出错:{classType}没有成功绑定数据,自动激活成功,但可能会抛出空异常!"); } //Mono类型能设置enabled if (clrInstance.GetType().IsSubclassOf(typeof(MonoBehaviour))) { ((MonoBehaviour)clrInstance).enabled = true; } //不管是啥类型,直接invoke这个awake方法 var awakeMethod = clrInstance.GetType().GetMethod("Awake", BindingFlags.Default | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Static); if (awakeMethod == null) { awakeMethod = t.GetMethod("Awake", BindingFlags.Default | BindingFlags.Public | BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Static); } else { awakeMethod.Invoke(clrInstance, null); classData.Activated = true; } if (awakeMethod == null) { Log.PrintError($"{t.FullName}不包含Awake方法,无法激活,已跳过"); } else if (!classData.Activated) { awakeMethod.Invoke(t, null); } classData.Activated = true; } Remove(); }
/// <summary> /// Add a classbind to gameobject to visualize /// 加ClassBind至GameObject以可视化 /// </summary> /// <param name="gameObject"></param> /// <param name="activeAfter"></param> /// <param name="type"></param> /// <returns></returns> private static string AddClassBind(GameObject gameObject, bool activeAfter, Type type) { var jBehaviour = type; var cb = gameObject.AddComponent <ClassBind>(); var _cb = new ClassData() { classNamespace = "", className = jBehaviour.FullName, activeAfter = activeAfter, }; var id = (cb.AddClass(_cb) as JBehaviour)._instanceID; cb.Active(_cb); UnityEngine.Object.Destroy(cb); return(id); }
/// <summary> /// Add a classbind to gameobject to visualize /// 加ClassBind至GameObject以可视化 /// </summary> /// <param name="gameObject"></param> /// <param name="activeAfter"></param> /// <param name="type"></param> /// <returns></returns> private static string AddClassBind(GameObject gameObject, bool activeAfter, Type type) { var jBehaviour = type; var cb = gameObject.AddComponent <ClassBind>(); var _cb = new ClassData() { classNamespace = jBehaviour.Namespace, className = jBehaviour.Name, activeAfter = activeAfter, useConstructor = true }; var id = cb.AddClass(_cb); cb.Active(_cb); UnityEngine.Object.Destroy(cb); return(id); }
/// <summary> /// Set value /// </summary> /// <param name="classData"></param> public void SetVal(ClassData classData) { string classType = $"{classData.classNamespace + (classData.classNamespace == "" ? "" : ".")}{classData.className}"; InitJEngine.Appdomain.LoadedTypes.TryGetValue(classType, out var type); Type t = type?.ReflectionType;//获取实际属性 //这里获取适配器类型接口,不直接获取Mono适配器了,因为不同的类型适配器不一样 var clrInstance = gameObject.GetComponents <CrossBindingAdaptorType>() .Last(clr => clr.ILInstance.Type == type as ILType); //绑定数据 if (classData.requireBindFields) { classData.BoundData = false; var fields = classData.fields.ToArray(); foreach (ClassField field in fields) { if (field.fieldType == ClassField.FieldType.NotSupported) { continue; } object obj = null; try { if (field.fieldType == ClassField.FieldType.Number) { var fieldType = t.GetField(field.fieldName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static).FieldType ?? t.GetProperty(field.fieldName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static).PropertyType; if (fieldType.FullName == typeof(SByte).FullName) { obj = SByte.Parse(field.value); classData.BoundData = true; } else if (fieldType.FullName == typeof(Byte).FullName) { obj = Byte.Parse(field.value); classData.BoundData = true; } else if (fieldType.FullName == typeof(Int16).FullName) { obj = Int16.Parse(field.value); classData.BoundData = true; } else if (fieldType.FullName == typeof(UInt16).FullName) { obj = UInt16.Parse(field.value); classData.BoundData = true; } else if (fieldType.FullName == typeof(Int32).FullName) { obj = Int32.Parse(field.value); classData.BoundData = true; } else if (fieldType.FullName == typeof(UInt32).FullName) { obj = UInt32.Parse(field.value); classData.BoundData = true; } else if (fieldType.FullName == typeof(Int64).FullName) { obj = Int64.Parse(field.value); classData.BoundData = true; } else if (fieldType.FullName == typeof(UInt64).FullName) { obj = UInt64.Parse(field.value); classData.BoundData = true; } else if (fieldType.FullName == typeof(Single).FullName) { obj = Single.Parse(field.value); classData.BoundData = true; } else if (fieldType.FullName == typeof(Decimal).FullName) { obj = Decimal.Parse(field.value); classData.BoundData = true; } else if (fieldType.FullName == typeof(Double).FullName) { obj = Double.Parse(field.value); classData.BoundData = true; } } else if (field.fieldType == ClassField.FieldType.String) { obj = field.value; classData.BoundData = true; } else if (field.fieldType == ClassField.FieldType.Bool) { field.value = field.value.ToLower(); obj = field.value == "true"; classData.BoundData = true; } if (field.fieldType == ClassField.FieldType.GameObject) { GameObject go = field.gameObject; if (go == null) { try { go = field.value == "${this}" ? gameObject : GameObject.Find(field.value); if (go == null) //找父物体 { go = FindSubGameObject(field); if (go == null) //如果父物体还不存在 { continue; } } } catch (Exception) //找父物体(如果抛出空异常) { go = FindSubGameObject(field); if (go == null) //如果父物体还不存在 { continue; } } } obj = go; classData.BoundData = true; } else if (field.fieldType == ClassField.FieldType.UnityComponent) { GameObject go = field.gameObject; if (go == null) { try { if (field.value.Contains(".")) { field.value = field.value.Remove(field.value.IndexOf(".", StringComparison.Ordinal)); } go = field.value == "${this}" ? gameObject : GameObject.Find(field.value); if (go == null) //找父物体 { go = FindSubGameObject(field); if (go == null) //如果父物体还不存在 { continue; } } } catch (Exception) //找父物体(如果抛出空异常) { go = FindSubGameObject(field); if (go == null) //如果父物体还不存在 { continue; } } } var tp = t.GetField(field.fieldName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); if (tp != null) { string tName = tp.FieldType.Name; if (tp.FieldType is ILRuntime.Reflection.ILRuntimeType) //如果在热更中 { var components = go.GetComponents <CrossBindingAdaptorType>(); foreach (var c in components) { if (c.ILInstance.Type.Name == tName) { obj = c.ILInstance; classData.BoundData = true; break; } } } else { var component = go.GetComponents <Component>().ToList() .Find(c => c.GetType().ToString().Contains(tName)); if (component != null) { obj = component; classData.BoundData = true; } } } else { var pi = t.GetProperty(field.fieldName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); if (pi != null) { string tName = pi.PropertyType.Name; if (pi.PropertyType is ILRuntime.Reflection.ILRuntimeType) //如果在热更中 { var components = go.GetComponents <CrossBindingAdaptorType>(); foreach (var c in components) { if (c.ILInstance.Type.Name == tName) { obj = c.ILInstance; classData.BoundData = true; break; } } } else { var component = go.GetComponents <Component>().ToList() .Find(c => c.GetType().ToString().Contains(tName)); if (component != null) { obj = component; classData.BoundData = true; } } } else { Log.PrintError( $"自动绑定{name}出错:{classType}.{field.fieldName}赋值出错:{field.fieldName}不存在"); } } } else if (field.fieldType == ClassField.FieldType.HotUpdateResource) { obj = Assets.LoadAsset(field.value, typeof(Object)).asset; classData.BoundData = true; } } catch (Exception except) { Log.PrintError( $"自动绑定{name}出错:{classType}.{field.fieldName}获取值{field.value}出错:{except.Message},已跳过"); } //如果有数据再绑定 if (classData.BoundData) { var fi = t.GetField(field.fieldName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); if (fi != null) { try { fi.SetValue(clrInstance.ILInstance, obj); } catch (Exception e) { Log.PrintError( $"自动绑定{name}出错:{classType}.{field.fieldName}赋值出错:{e.Message},已跳过"); } } else { //没FieldInfo尝试PropertyInfo var pi = t.GetProperty(field.fieldName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); if (pi != null) { pi.SetValue(clrInstance.ILInstance, obj); } else { Log.PrintError($"自动绑定{name}出错:{classType}不存在{field.fieldName},已跳过"); } } } } } }
/// <summary> /// Add class /// </summary> /// <param name="classData"></param> /// <returns></returns> public string AddClass(ClassData classData) { //添加脚本 string classType = $"{classData.classNamespace + (string.IsNullOrEmpty(classData.classNamespace) ? "" : ".")}{classData.className}"; if (!InitJEngine.Appdomain.LoadedTypes.TryGetValue(classType, out var type)) { Log.PrintError($"自动绑定{name}出错:{classType}不存在,已跳过"); return(null); } Type t = type.ReflectionType; //获取实际属性 //JBehaviour需自动赋值一个值 bool isMono = t.IsSubclassOf(typeof(MonoBehaviour)); bool isJBehaviour = false; if (!isMono)//不是mono才有可能继承JBehaviour { isJBehaviour = t.IsSubclassOf(jBehaviourType.ReflectionType); } bool needAdapter = t.BaseType != null && t.BaseType.GetInterfaces().Contains(typeof(CrossBindingAdaptorType)); ILTypeInstance instance; if (classData.useConstructor) { instance = isMono ? new ILTypeInstance(type as ILType, false) : InitJEngine.Appdomain.Instantiate(classType); } else { instance = new ILTypeInstance(type as ILType, !isMono); } instance.CLRInstance = instance; //这里是ClassBind的灵魂,我都佩服我自己这么写,所以别乱改这块 //非mono的跨域继承用特殊的,就是用JEngine提供的一个mono脚本,来显示字段,里面存ILTypeInstance //总之JEngine牛逼 //是继承Mono封装的基类,用自动生成的 if (needAdapter && isMono && t.BaseType?.FullName != typeof(MonoBehaviourAdapter.Adaptor).FullName && Type.GetType(t.BaseType?.FullName ?? string.Empty) != null) { Type adapterType = Type.GetType(t.BaseType?.FullName ?? string.Empty); if (adapterType == null) { Log.PrintError($"{t.FullName}, need to generate adapter"); return(null); } //直接反射赋值一波了 var clrInstance = gameObject.AddComponent(adapterType) as MonoBehaviour; var clrILInstance = t.GetField("instance", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); var clrAppDomain = t.GetField("appdomain", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); if (!(clrInstance is null)) { clrInstance.enabled = false; clrILInstance?.SetValue(clrInstance, instance); clrAppDomain?.SetValue(clrInstance, InitJEngine.Appdomain); instance.CLRInstance = clrInstance; } } //直接继承Mono的,非继承mono的,或不需要继承的,用这个 else { //挂个适配器到编辑器(直接继承mono,非继承mono,无需继承,都可以用这个) var clrInstance = gameObject.AddComponent <MonoBehaviourAdapter.Adaptor>(); clrInstance.enabled = false; clrInstance.ILInstance = instance; clrInstance.AppDomain = InitJEngine.Appdomain; //是MonoBehaviour继承,需要指定CLRInstance if (isMono && needAdapter) { instance.CLRInstance = clrInstance; } //判断类型 clrInstance.isMonoBehaviour = isMono; classData.Added = true; //JBehaviour额外处理 if (isJBehaviour) { clrInstance.isJBehaviour = true; var go = t.GetField("_gameObject", BindingFlags.Public); if (!(go is null)) { go.SetValue(clrInstance.ILInstance, gameObject); } } //JBehaviour返回实例ID if (isJBehaviour) { var f = t.GetField("_instanceID", BindingFlags.NonPublic); if (!(f is null)) { var id = f.GetValue(clrInstance.ILInstance).ToString(); return(id); } } } if (classData.useConstructor && isMono) { var m = type.GetConstructor(Extensions.EmptyParamList); if (m != null) { InitJEngine.Appdomain.Invoke(m, instance, null); } } return(null); }
/// <summary> /// Add class /// </summary> /// <param name="classData"></param> /// <returns></returns> public object AddClass(ClassData classData) { //添加脚本 string classType = $"{classData.classNamespace + (string.IsNullOrEmpty(classData.classNamespace) ? "" : ".")}{classData.className}"; if (!InitJEngine.Appdomain.LoadedTypes.TryGetValue(classType, out var type)) { Log.PrintError($"自动绑定{name}出错:{classType}不存在,已跳过"); return(null); } Type t = type.ReflectionType; //获取实际属性 classData.ClassType = t; Type baseType = t.BaseType is ILRuntimeWrapperType wrapperType ? wrapperType.RealType : t.BaseType; //这个地方太坑了 你一旦热更工程代码写的骚 就会导致ILWrapperType这个问题出现 一般人还真不容易发现这个坑 Type monoType = typeof(MonoBehaviour); //JBehaviour需自动赋值一个值 bool isMono = t.IsSubclassOf(monoType) || (baseType != null && baseType.IsSubclassOf(monoType)); bool needAdapter = baseType != null && baseType.GetInterfaces().Contains(typeof(CrossBindingAdaptorType)); ILTypeInstance instance = isMono ? new ILTypeInstance(type as ILType, false) : InitJEngine.Appdomain.Instantiate(classType); instance.CLRInstance = instance; /* * 这里是ClassBind的灵魂,我都佩服我自己这么写,所以别乱改这块 * 非mono的跨域继承用特殊的,就是用JEngine提供的一个mono脚本,来显示字段,里面存ILTypeInstance * 总之JEngine牛逼 * ClassBind只支持挂以下2种热更类型:纯热更类型,继承了Mono的类型(无论是主工程多重继承后跨域还是跨域后热更工程多重继承都可以) * 主工程多重继承后再跨域多重继承的应该还不支持 */ //主工程多重继承后跨域继承的生成适配器后用这个 if (needAdapter && isMono && baseType != typeof(MonoBehaviourAdapter.Adaptor)) { Type adapterType = Type.GetType(baseType.FullName ?? string.Empty); if (adapterType == null) { Log.PrintError($"{t.FullName}, need to generate adapter"); return(null); } //直接反射赋值一波了 var clrInstance = gameObject.AddComponent(adapterType) as MonoBehaviour; var clrILInstance = t.GetFields( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static) .First(f => f.Name == "instance" && f.FieldType == typeof(ILTypeInstance)); var clrAppDomain = t.GetFields( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static) .First(f => f.Name == "appdomain" && f.FieldType == typeof(AppDomain)); if (!(clrInstance is null)) { clrInstance.enabled = false; clrILInstance.SetValue(clrInstance, instance); clrAppDomain.SetValue(clrInstance, InitJEngine.Appdomain); instance.CLRInstance = clrInstance; classData.ClrInstance = (CrossBindingAdaptorType)clrInstance; } } //直接继承Mono的,热更工程多层继承mono的,非继承mono的,或不需要继承的,用这个 else { //挂个适配器到编辑器(直接继承mono,非继承mono,无需继承,都可以用这个) var clrInstance = gameObject.AddComponent <MonoBehaviourAdapter.Adaptor>(); clrInstance.enabled = false; clrInstance.ILInstance = instance; clrInstance.AppDomain = InitJEngine.Appdomain; classData.ClrInstance = clrInstance; //是MonoBehaviour继承,需要指定CLRInstance if (isMono) { instance.CLRInstance = clrInstance; } //判断类型 clrInstance.isMonoBehaviour = isMono; classData.Added = true; //JBehaviour额外处理 var go = t.GetField("_gameObject", BindingFlags.Public); go?.SetValue(clrInstance.ILInstance, gameObject); } if (isMono) { if (type.BaseType.ReflectionType is ILRuntimeType) { Log.PrintWarning( "因为有跨域多层继承MonoBehaviour,会有一个可以忽略的警告:You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all"); type.ReflectionType.GetConstructor(new Type[] { })?.Invoke(instance, new object[] { }); } else { var m = type.GetConstructor(Extensions.EmptyParamList); if (m != null) { InitJEngine.Appdomain.Invoke(m, instance, null); } } } return(instance); }
/// <summary> /// Set value /// </summary> /// <param name="classData"></param> public void SetVal(ClassData classData) { string classType = $"{classData.classNamespace + (classData.classNamespace == "" ? "" : ".")}{classData.className}"; Type t = classData.ClassType; //获取实际属性 var clrInstance = classData.ClrInstance; //绑定数据 classData.BoundData = false; var fields = classData.fields.ToArray(); var bindingAttr = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; foreach (ClassField field in fields) { if (field.fieldType == ClassField.FieldType.NotSupported) { continue; } object obj = null; try { if (field.fieldType == ClassField.FieldType.Number) { var fieldType = t.GetField(field.fieldName, bindingAttr).FieldType ?? (t.BaseType.GetField(field.fieldName, bindingAttr).FieldType ?? (t.GetProperty(field.fieldName, bindingAttr).PropertyType ?? t.BaseType.GetProperty(field.fieldName, bindingAttr).PropertyType)); fieldType = fieldType is ILRuntimeWrapperType wrapperType ? wrapperType.RealType : fieldType; if (fieldType == typeof(SByte)) { obj = SByte.Parse(field.value); classData.BoundData = true; } else if (fieldType == typeof(Byte)) { obj = Byte.Parse(field.value); classData.BoundData = true; } else if (fieldType == typeof(Int16)) { obj = Int16.Parse(field.value); classData.BoundData = true; } else if (fieldType == typeof(UInt16)) { obj = UInt16.Parse(field.value); classData.BoundData = true; } else if (fieldType == typeof(Int32)) { obj = Int32.Parse(field.value); classData.BoundData = true; } else if (fieldType == typeof(UInt32)) { obj = UInt32.Parse(field.value); classData.BoundData = true; } else if (fieldType == typeof(Int64)) { obj = Int64.Parse(field.value); classData.BoundData = true; } else if (fieldType == typeof(UInt64)) { obj = UInt64.Parse(field.value); classData.BoundData = true; } else if (fieldType == typeof(Single)) { obj = Single.Parse(field.value); classData.BoundData = true; } else if (fieldType == typeof(Decimal)) { obj = Decimal.Parse(field.value); classData.BoundData = true; } else if (fieldType == typeof(Double)) { obj = Double.Parse(field.value); classData.BoundData = true; } } else if (field.fieldType == ClassField.FieldType.String) { obj = field.value; classData.BoundData = true; } else if (field.fieldType == ClassField.FieldType.Bool) { field.value = field.value.ToLower(); obj = field.value == "true"; classData.BoundData = true; } if (field.fieldType == ClassField.FieldType.GameObject) { GameObject go = field.gameObject; if (go == null) { try { go = field.value == "${this}" ? gameObject : GameObject.Find(field.value); if (go == null) //找父物体 { go = FindSubGameObject(field); if (go == null) //如果父物体还不存在 { continue; } } } catch (Exception) //找父物体(如果抛出空异常) { go = FindSubGameObject(field); if (go == null) //如果父物体还不存在 { continue; } } } obj = go; classData.BoundData = true; } else if (field.fieldType == ClassField.FieldType.UnityComponent) { GameObject go = field.gameObject; if (go == null) { try { if (field.value.Contains(".")) { field.value = field.value.Remove(field.value.IndexOf(".", StringComparison.Ordinal)); } go = field.value == "${this}" ? gameObject : GameObject.Find(field.value); if (go == null) //找父物体 { go = FindSubGameObject(field); if (go == null) //如果父物体还不存在 { continue; } } } catch (Exception) //找父物体(如果抛出空异常) { go = FindSubGameObject(field); if (go == null) //如果父物体还不存在 { continue; } } } var tp = t.GetField(field.fieldName, bindingAttr); if (tp == null) { tp = t.BaseType?.GetField(field.fieldName, bindingAttr); } if (tp != null) { var fieldType = tp.FieldType; fieldType = fieldType is ILRuntimeWrapperType wrapperType ? wrapperType.RealType : fieldType; if (fieldType is ILRuntimeType) //如果在热更中 { var components = go.GetComponents <CrossBindingAdaptorType>(); foreach (var c in components) { if (c.ILInstance.Type.ReflectionType == fieldType) { obj = c.ILInstance; classData.BoundData = true; break; } } } else { var component = go.GetComponent(fieldType); if (component != null) { obj = component; classData.BoundData = true; } } } else { var pi = t.GetProperty(field.fieldName, bindingAttr); if (pi == null) { pi = t.BaseType?.GetProperty(field.fieldName, bindingAttr); } if (pi != null) { var fieldType = pi.PropertyType; fieldType = fieldType is ILRuntimeWrapperType wrapperType ? wrapperType.RealType : fieldType; if (fieldType is ILRuntimeType) //如果在热更中 { var components = go.GetComponents <CrossBindingAdaptorType>(); foreach (var c in components) { if (c.ILInstance.Type.ReflectionType == fieldType) { obj = c.ILInstance; classData.BoundData = true; break; } } } else { var component = go.GetComponent(fieldType); if (component != null) { obj = component; classData.BoundData = true; } } } else { Log.PrintError( $"自动绑定{name}出错:{classType}.{field.fieldName}赋值出错:{field.fieldName}不存在"); } } } else if (field.fieldType == ClassField.FieldType.HotUpdateResource) { obj = AssetMgr.Load(field.value); classData.BoundData = true; } } catch (Exception except) { Log.PrintError( $"自动绑定{name}出错:{classType}.{field.fieldName}获取值{field.value}出错:{except.Message},已跳过"); } //如果有数据再绑定 if (classData.BoundData) { void _setVal(MemberInfo mi) { try { switch (mi) { case null: throw new NullReferenceException(); case FieldInfo info: info.SetValue(clrInstance.ILInstance, obj); break; case PropertyInfo inf: inf.SetValue(clrInstance.ILInstance, obj); break; } } catch (Exception e) { Log.PrintError( $"自动绑定{name}出错:{classType}.{field.fieldName}赋值出错:{e.Message},已跳过"); } } var fi = t.GetField(field.fieldName, bindingAttr); if (fi == null) { fi = t.BaseType?.GetField(field.fieldName, bindingAttr); } if (fi != null) { _setVal(fi); } else { var pi = t.GetProperty(field.fieldName, bindingAttr); if (pi == null) { pi = t.BaseType?.GetProperty(field.fieldName, bindingAttr); } _setVal(pi); } } } }