C# CustomAttributeBuilder构造函数参数无效
我正在编写一个类,以根据其他类型动态生成类型,但修改了属性。在我将属性部分添加到问题之前,它可以正常工作,但在我添加以下用于处理属性的代码之后,在尝试创建CustomAttributeBuilder时,我得到了System.ArgumentExceptionC# CustomAttributeBuilder构造函数参数无效,c#,reflection.emit,C#,Reflection.emit,我正在编写一个类,以根据其他类型动态生成类型,但修改了属性。在我将属性部分添加到问题之前,它可以正常工作,但在我添加以下用于处理属性的代码之后,在尝试创建CustomAttributeBuilder时,我得到了System.ArgumentException class ModifiedTypeGenerator { Dictionary<Type, Dictionary<PropertyInfo, List<Attribute>>> modelInfo;
class ModifiedTypeGenerator {
Dictionary<Type, Dictionary<PropertyInfo, List<Attribute>>> modelInfo;
public List<Type> GenerateModifiedTypes(Dictionary<Type,Dictionary<PropertyInfo,List<Attribute>>> models)
{
modelInfo = models;
List<Type> toReturn = new List<Type>();
foreach(Type model in modelInfo.Keys)
{
TypeBuilder tb = CreateTypeBuilder(model);
ConstructurBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
foreach(PropertyInfo propertyInfo in modelInfo[model].Keys)
{
CreateProperty(tb,model,propertyInfo);
}
Type newType = tb.CreateType();
toReturn.Add(newType);
}
return toReturn;
}
private TypeBuilder CreateTypeBuilder(Type model)
{
string typeName = "modified_" + model.Name;
AssemblyName assemblyName = new AssemblyName(typeName);
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("Module");
TypeBuilder typeBuilder = moduleBuilder.DefineType(typeName,
TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout,
model
);
return typeBuilder;
}
private void CreateProperty(TypeBuilder typeBuilder, Type model, PropertyInfo propertyInfo)
{
FieldBuilder fieldBuilder = typeBuilder.DefineField("_" + propertyInfo.Name, propertyInfo.PropertyType, FieldAttributes.Public);
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(propertyInfo.Name, PropertyAttributes.HasDefault, propertyInfo.PropertyType, null);
MethodBuilder getMethodBuilder = typeBuilder.DefineMethod("get_" + propertyInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyInfo.PropertyType, Type.EmptyTypes);
MethodBuilder setMethodBuilder = typeBuilder.DefineMethod("set_" + propertyInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, null, new[] { propertyInfo.PropertyType });
ILGenerator getIl = getMethodBuilder.GetILGenerator();
getIl.Emit(OpCodes.Ldarg_0);
getIl.Emit(OpCodes.Ldfld, fieldBuilder);
getIl.Emit(OpCodes.Ret);
ILGenerator setIl = setMethodBuilder.GetILGenerator();
Label modifyProperty = setIl.DefineLabel();
Label exitSet = setIl.DefineLabel();
setIl.MarkLabel(modifyProperty);
setIl.Emit(OpCodes.Ldarg_0);
setIl.Emit(OpCodes.Ldarg_1);
setIl.Emit(OpCodes.Stfld, fieldBuilder);
setIl.Emit(OpCodes.Nop);
setIl.MarkLabel(exitSet);
setIl.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getMethodBuilder);
propertyBuilder.SetSetMethod(setMethodBuilder);
AddAttributes(propertyBuilder,model,propertyInfo);
}
private void AddAttributes(PropertyBuilder propertyBuilder, Type model, PropertyInfo propertyInfo)
{
foreach(var attribute in modelInfo[model][propertyInfo])
{
CustomAttributeData customAttributeData =
propertyInfo.CustomAttributes.First(x => x.AttributeType == attribute.GetType());
var constructorArguments =
customAttributeData.ConstructorArguments.Select(x => x as object).ToArray();
CustomAttributeBuilder customAttributeBuilder =
new CustomAttributeBuilder(customAttributeData.Constructor, constructorArguments);
propertyBuilder.SetCustomAttribute(customAttributeBuilder);
}
}
}
类修改类型生成器{
字典模型信息;
公共列表生成修改类型(字典模型)
{
modelInfo=模型;
List toReturn=新列表();
foreach(modelInfo.Keys中的类型model)
{
TypeBuilder tb=CreateTypeBuilder(模型);
ConstructurBuilder constructor=tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
foreach(模型信息[model].Keys中的PropertyInfo PropertyInfo)
{
CreateProperty(tb、模型、propertyInfo);
}
类型newType=tb.CreateType();
toReturn.Add(新类型);
}
回归回归;
}
私有类型生成器CreateTypeBuilder(类型模型)
{
字符串typeName=“modified_933;”+model.Name;
AssemblyName AssemblyName=新的AssemblyName(typeName);
AssemblyBuilder AssemblyBuilder=AppDomain.CurrentDomain.DefinedDynamicAssembly(assemblyName,AssemblyBuilderAccess.Run);
ModuleBuilder ModuleBuilder=assemblyBuilder.DefinedDynamicModule(“模块”);
TypeBuilder TypeBuilder=moduleBuilder.DefineType(typeName,
TypeAttributes.Public|
TypeAttributes.Class|
TypeAttributes.AutoClass|
TypeAttributes.AnsiClass|
TypeAttributes.BeforeFieldInit|
TypeAttributes.AutoLayout,
模型
);
返回类型生成器;
}
私有void CreateProperty(TypeBuilder TypeBuilder,类型模型,PropertyInfo PropertyInfo)
{
FieldBuilder FieldBuilder=typeBuilder.DefineField(“\u”+propertyInfo.Name、propertyInfo.PropertyType、FieldAttributes.Public);
PropertyBuilder PropertyBuilder=typeBuilder.DefineProperty(propertyInfo.Name,PropertyAttributes.HasDefault,propertyInfo.PropertyType,null);
MethodBuilder getMethodBuilder=typeBuilder.DefineMethod(“get|”+propertyInfo.Name,MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,propertyInfo.PropertyType,Type.EmptyTypes);
MethodBuilder setMethodBuilder=typeBuilder.DefineMethod(“set_”+propertyInfo.Name,MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig,null,new[]{propertyInfo.PropertyType});
ILGenerator getIl=getMethodBuilder.GetILGenerator();
getIl.Emit(操作码.Ldarg_0);
getIl.Emit(操作码.Ldfld,fieldBuilder);
getIl.Emit(操作码.Ret);
ILGenerator setIl=setMethodBuilder.GetILGenerator();
Label modifyProperty=setIl.DefineLabel();
Label exitSet=setIl.DefineLabel();
setIl.MarkLabel(modifyProperty);
setIl.Emit(操作码.Ldarg_0);
setIl.Emit(操作码Ldarg_1);
setIl.Emit(操作码.Stfld,fieldBuilder);
setIl.Emit(操作码Nop);
设置标记标签(exitSet);
setIl.Emit(操作码Ret);
SetGetMethod(getMethodBuilder);
propertyBuilder.SetSetMethod(setMethodBuilder);
添加属性(propertyBuilder、模型、propertyInfo);
}
私有void AddAttributes(PropertyBuilder PropertyBuilder,类型模型,PropertyInfo PropertyInfo)
{
foreach(modelInfo[model][propertyInfo]中的var属性)
{
CustomAttributeData CustomAttributeData=
propertyInfo.CustomAttributes.First(x=>x.AttributeType==attribute.GetType());
变量构造函数参数=
customAttributeData.ConstructorArguments.Select(x=>x作为对象).ToArray();
CustomAttributeBuilder CustomAttributeBuilder=
新的CustomAttributeBuilder(customAttributeData.Constructor、Constructor Arguments);
SetCustomAttribute(customAttributeBuilder);
}
}
}
可通过以下方式运行的示例类型:
public class TestModel
{
[RangeAttribute(1,100)]
public int Count { get; set;}
}
class Program
{
static void Main(string[] args)
{
List<Type> types = new List<Type>();
types.Add(typeof(TestModel));
GetModifiedTypes(types);
}
public static List<Type> GetModifiedTypes(List<Type> models)
{
Dictionary<Type, Dictionary<PropertyInfo, List<Attribute>>> modelInfo = new Dictionary<Type, Dictionary<PropertyInfo, List<Attribute>>>();
foreach(Type model in models)
{
modelInfo.Add(model, new Dictionary<PropertyInfo, List<Attribute>>());
foreach(PropertyInfo propertyInfo in model.GetProperties())
{
var customAttributeDataList = propertyInfo.GetCustomAttributes(typeof(Attribute), true).Select(x => x as Attribute).ToList();
for (int i = 0; i < customAttributeDataList.Count(); i++)
{
var atr= customAttributeDataList[i] as dynamic;
customAttributeDataList[i] = GetModifiedAttribute(atr);
}
modelInfo[model].Add(propertyInfo, customAttributeDataList);
}
}
ModifiedTypeGenerator mtg = new ModifiedTypeGenerator();
return mtg.GenerateModifiedTypes(modelInfo);
}
public static Attribute GetModifieAttribute(Attribute attribute)
{
return attribute;
}
public static RangeAttribute GetModifiedAttribute(RangeAttribute attribute)
{
Random r = new Random();
return new RangeAttribute(r.Next(), r.Next());
}
}
公共类测试模型
{
[秘书长(1100)]
公共整数计数{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
列表类型=新列表();
添加(typeof(TestModel));
GetModifiedTypes(类型);
}
公共静态列表GetModifiedTypes(列表模型)
{
Dictionary modelInfo=新字典();
foreach(模型中的类型模型)
{
添加(model,newdictionary());
foreach(模型中的PropertyInfo PropertyInfo.GetProperties())
{
var customAttributeDataList=propertyInfo.GetCustomAttributes(typeof(Attribute),true)。选择(x=>x作为属性)。ToList();
对于(int i=0;i
问题是由以下代码位引起的:
var constructorArguments = customAttributeData
.ConstructorArguments.Select(x => x as object).ToArray();
这里,CustomAttributeData.ConstructorArguments
IList
,其元素(类型为customAttributeTypeArguments
)装箱为对象
并尝试用作接受两个int32
参数的构造函数的参数。由于它们实际上不是int32
类型,
var constructorArguments = customAttributeData
.ConstructorArguments.Select(x => (object)x.Value).ToArray();