/// <summary>
 /// 获取参数类型的字符串,此处处理一些特殊的字符串
 /// </summary>
 /// <param name="paramData"></param>
 /// <returns></returns>
 public static void GetParameterTypeStr(ref ParamData paramData)
 {
     if (paramData.Prefix == ParamPrefix.Ref || paramData.Prefix == ParamPrefix.Out)
     {
         paramData.ParamTypeStr = paramData.ParamTypeStr.Replace("&", "");
     }
 }
        /// <summary>
        /// 获取参数前缀
        /// </summary>
        /// <param name="paramData"></param>
        /// <returns></returns>
        public static string GetParameterPrefix(ParamData paramData)
        {
            string paramPrefix = string.Empty;

            switch (paramData.Prefix)
            {
            case ParamPrefix.None:
                paramPrefix = "";
                break;

            case ParamPrefix.Ref:
                paramPrefix = "ref";
                break;

            case ParamPrefix.Out:
                paramPrefix = "out";
                break;
            }

            return(paramPrefix);
        }
        /// <summary>
        /// 加载所有需要保护的方法
        /// </summary>
        /// <param name="mainPath"></param>
        /// <returns></returns>
        private static List <ProtectMethodInfo> LoadProtectMethods(string mainPath)
        {
            List <ProtectMethodInfo> methodInfos = new List <ProtectMethodInfo>();
            Assembly assembly = Assembly.LoadFile(mainPath);
            var      types    = assembly.GetTypes();

            BindingFlags flags = BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly;

            List <Type> targetTypes = new List <Type>();

            foreach (var type in types)
            {
                var attribute = type.GetCustomAttribute(typeof(AllowHotfixAttribute)) as AllowHotfixAttribute;
                if (attribute != null)
                {
                    targetTypes.Add(type);
                }
            }

            foreach (var type in targetTypes)
            {
                var methods = type.GetMethods(flags);

                //==============================================================
                //遍历所有方法,提取所有可以进行热更修复的方法
                //注意:
                //1.params 修饰的参数 不可被修复
                //
                //==============================================================
                foreach (var method in methods)
                {
                    ProtectMethodInfo methodInfo = new ProtectMethodInfo();
                    List <ParamData>  paramDatas = new List <ParamData>();

                    //获取参数信息
                    bool          isPassParameterTest = true;
                    StringBuilder parameter           = new StringBuilder();
                    var           parameters          = method.GetParameters();
                    foreach (var param in parameters)
                    {
                        ParamData paramData = new ParamData();
                        if (param.IsDefined(typeof(System.ParamArrayAttribute)))
                        {//暂时不支持可选参数数组
                            UnityEngine.Debug.Log("not support this type parameter!");
                            isPassParameterTest = false;
                            break;
                        }

                        if (param.ParameterType.IsByRef && param.IsOut)
                        {//out 遇上述条件不是并列关系 out 修饰的参数既是ref 也是 out
                            paramData.Prefix       = ParamPrefix.Out;
                            paramData.ParamTypeStr = param.ParameterType.ToString();
                            //===================暂时不支持ref参数,适配器原因======================
                            UnityEngine.Debug.Log("not support this type parameter!");
                            isPassParameterTest = false;
                            break;
                        }
                        else if (param.ParameterType.IsByRef && !param.IsOut)
                        {//ref
                            paramData.Prefix       = ParamPrefix.Ref;
                            paramData.ParamTypeStr = param.ParameterType.ToString();
                            //==================暂时不支持out参数,适配器原因=======================
                            UnityEngine.Debug.Log("not support this type parameter!");
                            isPassParameterTest = false;
                            break;
                        }
                        else if (!param.ParameterType.IsByRef && !param.IsOut)
                        {//normal
                            paramData.Prefix       = ParamPrefix.None;
                            paramData.ParamTypeStr = param.ParameterType.ToString();
                        }
                        else
                        {
                            UnityEngine.Debug.Log("not support this type parameter!");
                            isPassParameterTest = false;
                            break;
                        }
                        string paramPrefix = GetParameterPrefix(paramData);
                        GetParameterTypeStr(ref paramData);

                        parameter.Append("0" + (string.IsNullOrWhiteSpace(paramPrefix) ? "" : paramPrefix + "_") + paramData.ParamTypeStr + "_");
                        paramDatas.Add(paramData);
                    }

                    if (!isPassParameterTest)
                    {
                        UnityEngine.Debug.LogError(method.Name + "未通过参数测试!");
                        continue;
                    }

                    //获取参数信息
                    methodInfo.paramList = paramDatas;

                    //获取返回值信息
                    methodInfo.ReturnTypeStr = method.ReturnType.ToString();

                    //方法名称
                    methodInfo.MethodName = (method.DeclaringType.ToString() + "_NM_" + method.Name + "_IN_" + parameter.ToString().TrimEnd('_') + "_OUT_" + methodInfo.ReturnTypeStr).Replace(".", "_").TrimEnd('_');

                    methodInfos.Add(methodInfo);
                }
            }

            //测试获取的方法
            //foreach (var mi in methodInfos)
            //{
            //    UnityEngine.Debug.Log("methodName: \n" + mi.MethodName);
            //}

            return(methodInfos);
        }