关于#java#的问题:问题可能出在创建类型时使用了"_"作为字段名的前缀,导致生成的属性名称包含了下划线

该问题来自社区帖: https://bbs.csdn.net/topics/615210839.为符合问答规范, 该问题经过ChatGPT优化

public static Type CreateProxyType()
        {

            //获得当前的程序域
            AppDomain currentDomain = Thread.GetDomain();
            //创建这个类的程序集
            AssemblyName assemblyName = new AssemblyName("ProxyServiceClass");
            AssemblyBuilder assemblyBuilder = currentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
            //创建模块
            ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("ProxyServiceClass", "ProxyServiceClass.dll");

            //创建类型:传入父类、接口参数
            TypeBuilder typeBuilder = moduleBuilder.DefineType("ProxyServiceClass", TypeAttributes.Public, typeof(ServiceClass));

            var field = typeBuilder.DefineField("_interceptor", typeof(IInterceptor), FieldAttributes.Private);

            MethodInfo befMet = typeof(ProxyInterceptor).GetMethod("InterceptBef");
            MethodInfo aftMet = typeof(ProxyInterceptor).GetMethod("InterceptAft");

            var consmt = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);

            ConstructorInfo constructorInfo = typeof(ProxyInterceptor).GetConstructor(Type.EmptyTypes);
            ConstructorInfo baseConst = typeof(ServiceClass).GetConstructor(Type.EmptyTypes);

            var ilconst = consmt.GetILGenerator();
            ilconst.DeclareLocal(typeof(ProxyInterceptor));

            ilconst.Emit(OpCodes.Ldarg_0);
            ilconst.Emit(OpCodes.Call, baseConst);
            ilconst.Emit(OpCodes.Newobj, constructorInfo);
            ilconst.Emit(OpCodes.Stloc_0);
            ilconst.Emit(OpCodes.Ldarg_0);
            ilconst.Emit(OpCodes.Ldloc_0);
            ilconst.Emit(OpCodes.Stfld, field);
            ilconst.Emit(OpCodes.Pop);
            ilconst.Emit(OpCodes.Ret);

            MethodInfo[] methods = typeof(ServiceClass).GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
            foreach (var item in methods)
            {

                if (!item.IsVirtual)
                    continue;

                var parTypes = item.GetParameters().Select(x => x.ParameterType).ToArray();
                MethodBuilder mb = typeBuilder.DefineMethod(item.Name, MethodAttributes.Public | MethodAttributes.Virtual, item.ReturnType, parTypes ?? Type.EmptyTypes);
                ILGenerator il = mb.GetILGenerator();

                // 声明方法内部的局部变量、返回参数
                if (item.ReturnType != typeof(void))
                    il.DeclareLocal(item.ReturnType);
                foreach (var parType in parTypes)
                    il.DeclareLocal(parType);

                il.Emit(OpCodes.Nop);
                // this._interceptor.InterceptBef();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, field);
                il.EmitCall(OpCodes.Callvirt, befMet, Type.EmptyTypes);

                // base.xxx(proxy function)
                il.Emit(OpCodes.Ldarg_0);
                for (int i = 0; i < parTypes.Length; i++)
                {
                    il.Emit(OpCodes.Ldarg, i + 1);
                }
                il.EmitCall(OpCodes.Call, item, parTypes);

                if (item.ReturnType != typeof(void))
                    il.Emit(OpCodes.Stloc_0);

                // this._interceptor.InterceptAft();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, field);
                il.EmitCall(OpCodes.Callvirt, aftMet, Type.EmptyTypes);

                if (item.ReturnType != typeof(void))
                    il.Emit(OpCodes.Ldloc_0);
                else
                    il.Emit(OpCodes.Pop);
                il.Emit(OpCodes.Ret);
            }

            Type retType = typeBuilder.CreateType();
            assemblyBuilder.Save("ProxyServiceClass.dll");

            return retType;
        }

public class ServiceClass
    {

        public virtual string GetDataById(int id)
        {
            return $"GetDataById return {id}";
        }

        public virtual void UpdateById(int id)
        {
        }

        public virtual string SelectById()
        {
            return "SelectById";
        }

        public virtual void DeleteById()
        {
        }

    }

// 想生成的类

public class ProxyServiceClass2 : ServiceClass
    {

        private IInterceptor _interceptor;

        public ProxyServiceClass2()
        {
            this._interceptor = new ProxyInterceptor();
        }

        public override string GetDataById(int id)
        {
            string resultStr;
            _interceptor.InterceptBef();
            resultStr = base.GetDataById(id);
            _interceptor.InterceptAft();
            return resultStr;
        }

        public override void UpdateById(int id)
        {
            _interceptor.InterceptBef();
            base.UpdateById(id);
            _interceptor.InterceptAft();
        }

        public override string SelectById()
        {
            string resultStr;
            _interceptor.InterceptBef();
            resultStr = base.SelectById();
            _interceptor.InterceptAft();
            return resultStr;
        }

        public override void DeleteById()
        {
            _interceptor.InterceptBef();
            base.DeleteById();
            _interceptor.InterceptAft();
        }

    }

问题可能出在创建类型时使用了"_"作为字段名的前缀,导致生成的属性名称包含了下划线。可以尝试将所有的"_"前缀改为其他字符。

  • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/486862
  • 以下回答由chatgpt基于相关博客总结生成:

    在Java中,命名规范不鼓励使用""作为字段名的前缀。可以通过重构代码,将所有的""前缀改为其他字符,比如通过camelCase或者PascalCase的方式来命名。例如,将"_firstName"改为"firstName"或者"FirstName"。

    具体做法:

    1. 打开Java代码文件,在编辑器中使用“查找并替换”功能,找到所有以""开头的字段名。比如,用Eclipse编辑器的“查找”功能,在搜索框中输入“[a-z]”,按下回车。

    2. 选中所有被找到的字段名,将它们改为camelCase或者PascalCase格式的字段名,比如“firstName”或者“FirstName”。

    3. 在修改后的代码中测试程序,确保其正常运行。