使用反射在运行时创建的类型的 属性 上添加属性
Add attribute on property of a runtime created type using reflection
我试图在运行时创建一个类型,在我添加到该类型上的每个 属性 上粘贴一个 StuckAttribute
属性。
类型生成器:
private TypeBuilder getTypeBuilder()
{
var typeSignature = "IDynamicFlattenedType";
var an = new AssemblyName(typeSignature);
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicDomain");
TypeBuilder tb = moduleBuilder.DefineType(typeSignature
, TypeAttributes.Public |
TypeAttributes.Interface) |
TypeAttributes.Abstract |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass
, null);
return tb;
}
属性 建造者:
private void createProperty(TypeBuilder tb, string propertyName, Type propertyType)
{
Type[] ctorParams = new Type[] { typeof(string) };
ConstructorInfo classCtorInfo = typeof(StuckAttribute).GetConstructor(ctorParams);
CustomAttributeBuilder myCABuilder2 = new CustomAttributeBuilder(
classCtorInfo,
new object[] { DateTime.Now.ToString() });
PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
propertyBuilder.SetCustomAttribute(myCABuilder2);
MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName,
MethodAttributes.Public |
MethodAttributes.Abstract |
MethodAttributes.Virtual |
MethodAttributes.HideBySig |
MethodAttributes.NewSlot,
CallingConventions.HasThis,
propertyType,
Type.EmptyTypes
);
getPropMthdBldr.SetImplementationFlags(MethodImplAttributes.Managed);
MethodBuilder setPropMthdBldr =
tb.DefineMethod("set_" + propertyName,
MethodAttributes.Public |
MethodAttributes.Abstract |
MethodAttributes.Virtual |
MethodAttributes.HideBySig |
MethodAttributes.NewSlot,
CallingConventions.HasThis,
null, new[] { propertyType });
setPropMthdBldr.SetImplementationFlags(MethodImplAttributes.Managed);
propertyBuilder.SetGetMethod(getPropMthdBldr);
propertyBuilder.SetSetMethod(setPropMthdBldr);
}
我创建了一个简单的测试来检查 StuckAttribute
是否在属性上。如您所见,我正在尝试对每个 PropertyInfo
元素调用 GetCustomAttributes()
属性。
[Test]
public void test()
{
Type flattenedType = Reflection.Classes.FlattenClassBuilder.flattenType<TestClass>(this.classes);
flattenedType.Should().NotBeNull();
PropertyInfo[] properties = flattenedType.GetProperties();
properties.Should().NotBeEmpty().And.HaveCount(4);
IEnumerable<Attribute> attrs = properties[0].GetCustomAttributes();
attrs.Should().NotBeEmpty();
}
然而它失败了。它在最后一个断言上失败:
attrs.Should().NotBeEmpty();
我做错了什么?
已解决:
我创建了 StuckAttribute
作为内部 class。我已经解决了将访问器 class 设置为 public
.
所以,我的测试现在运行:
PropertyInfo[] properties = flattenedType.GetProperties();
properties.Should().NotBeEmpty().And.HaveCount(4);
properties.Should().OnlyContain(p => p.GetCustomAttribute<Reflection.Classes.FieldPropertyOwnerAttribute>() != null);
我试图在运行时创建一个类型,在我添加到该类型上的每个 属性 上粘贴一个 StuckAttribute
属性。
类型生成器:
private TypeBuilder getTypeBuilder()
{
var typeSignature = "IDynamicFlattenedType";
var an = new AssemblyName(typeSignature);
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicDomain");
TypeBuilder tb = moduleBuilder.DefineType(typeSignature
, TypeAttributes.Public |
TypeAttributes.Interface) |
TypeAttributes.Abstract |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass
, null);
return tb;
}
属性 建造者:
private void createProperty(TypeBuilder tb, string propertyName, Type propertyType)
{
Type[] ctorParams = new Type[] { typeof(string) };
ConstructorInfo classCtorInfo = typeof(StuckAttribute).GetConstructor(ctorParams);
CustomAttributeBuilder myCABuilder2 = new CustomAttributeBuilder(
classCtorInfo,
new object[] { DateTime.Now.ToString() });
PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
propertyBuilder.SetCustomAttribute(myCABuilder2);
MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName,
MethodAttributes.Public |
MethodAttributes.Abstract |
MethodAttributes.Virtual |
MethodAttributes.HideBySig |
MethodAttributes.NewSlot,
CallingConventions.HasThis,
propertyType,
Type.EmptyTypes
);
getPropMthdBldr.SetImplementationFlags(MethodImplAttributes.Managed);
MethodBuilder setPropMthdBldr =
tb.DefineMethod("set_" + propertyName,
MethodAttributes.Public |
MethodAttributes.Abstract |
MethodAttributes.Virtual |
MethodAttributes.HideBySig |
MethodAttributes.NewSlot,
CallingConventions.HasThis,
null, new[] { propertyType });
setPropMthdBldr.SetImplementationFlags(MethodImplAttributes.Managed);
propertyBuilder.SetGetMethod(getPropMthdBldr);
propertyBuilder.SetSetMethod(setPropMthdBldr);
}
我创建了一个简单的测试来检查 StuckAttribute
是否在属性上。如您所见,我正在尝试对每个 PropertyInfo
元素调用 GetCustomAttributes()
属性。
[Test]
public void test()
{
Type flattenedType = Reflection.Classes.FlattenClassBuilder.flattenType<TestClass>(this.classes);
flattenedType.Should().NotBeNull();
PropertyInfo[] properties = flattenedType.GetProperties();
properties.Should().NotBeEmpty().And.HaveCount(4);
IEnumerable<Attribute> attrs = properties[0].GetCustomAttributes();
attrs.Should().NotBeEmpty();
}
然而它失败了。它在最后一个断言上失败:
attrs.Should().NotBeEmpty();
我做错了什么?
已解决:
我创建了 StuckAttribute
作为内部 class。我已经解决了将访问器 class 设置为 public
.
所以,我的测试现在运行:
PropertyInfo[] properties = flattenedType.GetProperties();
properties.Should().NotBeEmpty().And.HaveCount(4);
properties.Should().OnlyContain(p => p.GetCustomAttribute<Reflection.Classes.FieldPropertyOwnerAttribute>() != null);