protected override void Context() { base.Context(); _onlyVariable = ParameterFlag.CanBeVaried; _variableAndMinIsAllowedAndMaxIsAllowed = ParameterFlag.CanBeVaried; _variableAndMinIsAllowedAndMaxIsAllowed ^= ParameterFlag.MinIsAllowed; _variableAndMinIsAllowedAndMaxIsAllowed ^= ParameterFlag.MaxIsAllowed; }
/// <summary> /// TCP 参数类型 /// </summary> /// <param name="parameters">参数集合</param> /// <param name="returnType">类型</param> /// <param name="flag">TCP 参数类型配置</param> internal ParameterHash(ParameterInfo[] parameters, Type returnType, ParameterFlag flag) { this.parameters = parameters; this.returnType = returnType; this.flag = flag; hashCode = (int)flag; if (returnType != typeof(void)) { returnType.GetHashCode(); } int index = 0; foreach (ParameterInfo parameter in parameters) { hashCode ^= (parameter.elementType().GetHashCode() ^ parameter.Name.GetHashCode()) + index++; } }
/// <summary> /// 获取 TCP 参数类型 /// </summary> /// <param name="parameters">参数集合</param> /// <param name="returnType">类型</param> /// <param name="isSerializeReferenceMember">是否检测相同的引用成员</param> /// <param name="isSerializeBox">IsSerializeBox</param> /// <returns></returns> internal static ParameterType Get(ParameterInfo[] parameters, Type returnType, bool isSerializeReferenceMember, bool isSerializeBox) { ParameterFlag flag = isSerializeReferenceMember ? ParameterFlag.IsSerializeReferenceMember : ParameterFlag.None; if (isSerializeBox && parameters.Length == (returnType == typeof(void) ? 1 : 0)) { flag |= ParameterFlag.IsSerializeBox; } ParameterHash parameterType = new ParameterHash(parameters.Length > 1 ? parameters.copy().sort(compare) : parameters, returnType, flag); ParameterType type; Monitor.Enter(typeLock); if (types.TryGetValue(parameterType, out type)) { Monitor.Exit(typeLock); return(type); } try { Type[] interfaces; if (returnType == typeof(void)) { interfaces = null; } else { interfaces = returnInterfaces; if (!returnInterfaceTypes.TryGetValue(returnType, out interfaces[0])) { returnInterfaceTypes.Add(returnType, interfaces[0] = typeof(AutoCSer.Net.IReturnParameter <>).MakeGenericType(returnType)); } } TypeBuilder typeBuilder = AutoCSer.Emit.Builder.Module.Builder.DefineType("AutoCSer.Net.TcpServer.Emit.ParameterType" + (++typeIndex).toString(), TypeAttributes.AutoLayout | TypeAttributes.Public, typeof(ValueType), interfaces); foreach (ParameterInfo parameter in parameters) { typeBuilder.DefineField(parameter.Name, parameter.elementType(), FieldAttributes.Public); } if (returnType != typeof(void)) { FieldBuilder returnFieldBuilder = typeBuilder.DefineField(ReturnValue.RetParameterName, returnType, FieldAttributes.Public); returnFieldBuilder.SetCustomAttribute(new CustomAttributeBuilder(jsonIgnoreMemberAttributeConstructorInfo, EmptyArray <object> .Array)); PropertyInfo returnProperty = interfaces[0].GetProperty(ReturnValue.ReturnParameterName); MethodInfo returnPropertyGetMethod = returnProperty.GetGetMethod(); MethodBuilder getReturnMethodBuilder = typeBuilder.DefineMethod(returnPropertyGetMethod.Name, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, returnPropertyGetMethod.ReturnType, null); ILGenerator getReturnGenerator = getReturnMethodBuilder.GetILGenerator(); getReturnGenerator.Emit(OpCodes.Ldarg_0); getReturnGenerator.Emit(OpCodes.Ldfld, returnFieldBuilder); getReturnGenerator.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(getReturnMethodBuilder, returnPropertyGetMethod); MethodInfo returnPropertySetMethod = returnProperty.GetSetMethod(); returnTypes[0] = returnType; MethodBuilder setReturnMethodBuilder = typeBuilder.DefineMethod(returnPropertySetMethod.Name, MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.SpecialName, returnPropertySetMethod.ReturnType, returnTypes); ILGenerator setReturnGenerator = setReturnMethodBuilder.GetILGenerator(); setReturnGenerator.Emit(OpCodes.Ldarg_0); setReturnGenerator.Emit(OpCodes.Ldarg_1); setReturnGenerator.Emit(OpCodes.Stfld, returnFieldBuilder); setReturnGenerator.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(setReturnMethodBuilder, returnPropertySetMethod); //AutoCSer.Net.IReturnParameter<@MethodReturnType.FullName> PropertyBuilder returnPropertyBuilder = typeBuilder.DefineProperty(ReturnValue.ReturnParameterName, PropertyAttributes.None, returnProperty.PropertyType, null); returnPropertyBuilder.SetGetMethod(getReturnMethodBuilder); returnPropertyBuilder.SetSetMethod(setReturnMethodBuilder); } typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(serializeAttributeConstructorInfo, (flag & ParameterFlag.IsSerializeReferenceMember) == 0 ? falseParameter : trueParameter)); if ((flag & ParameterFlag.IsSerializeBox) != 0) { typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(boxSerializeAttributeConstructorInfo, EmptyArray <object> .Array)); } type = new ParameterType { Type = typeBuilder.CreateType(), Index = typeIndex }; type.setFields(type.Type.GetFields()); types.Add(parameterType, type); } finally { Monitor.Exit(typeLock); } return(type); }