创建具有可为 null 属性的 CustomAttributeBuilder
在使用 TypeBuilder 和 PropertyBuilder 创建类型和属性时,我需要添加自定义属性。但是,我尝试创建的 API 会尽可能多地抽象反射内容,因此为了向类型或属性添加属性,用户需要提供实际的属性。
但由于属性无法添加到 TypeBuilder 或 PropertyBuilder (据我所知),我需要使用提供的属性中的匹配值创建 CustomAttributeBuilder 的实例(可以添加)。我使用下面的方法来执行此操作,并且效果很好,除非属性具有可为 null 的属性。
如果属性包含可为 null 的属性,则会引发 ArgumentException,指出“无效类型用作自定义属性构造函数参数、字段或属性”。当执行该方法的最后一行时。
private static CustomAttributeBuilder CreateAttributeWithValuesFromTemplate(
Attribute attribute)
{
var propertiesWithValues = new List<PropertyInfo>();
var nonNullPropertyValues = new List<Object>();
if (attribute != null)
{
var properties = GetWritableProperties(attribute);
object[] propertyValues = GetPropertyValues(attribute, properties);
for (int i = 0; i < properties.Length; i++)
{
if (propertyValues[i] == null)
continue;
propertiesWithValues.Add(properties[i]);
nonNullPropertyValues.Add(propertyValues[i]);
}
}
ConstructorInfo constructor;
if (attributeSpecification.Constructor != null)
constructor = attributeSpecification.Constructor;
else
constructor = attributeSpecification.Type.GetConstructor(new Type[] { });
object[] constructorParams;
if (attributeSpecification.Constructor != null)
constructorParams = attributeSpecification.ConstructorParameters;
else
constructorParams = new object[] {};
return new CustomAttributeBuilder(constructor, constructorParams,
propertiesWithValues.ToArray(), nonNullPropertyValues.ToArray());
}
我尝试修改方法来检查属性是否属于可为空类型,但我还没有找到实际提供可为空值的方法,即下面的代码(这只是一个测试)不起作用因为 nullableValue.GetType() 将返回 Int32。
if(properties[i].PropertyType.IsGenericType
&& properties[i].PropertyType.GetGenericTypeDefinition()== typeof(Nullable<>)) {
Nullable<int> nullableValue = new Nullable<int>();
nonNullPropertyValues.Add(nullableValue);
} else {
nonNullPropertyValues.Add(propertyValues[i]);
}
任何正确方向的解决方案或指针将不胜感激。
While creating types and properties with TypeBuilder and PropertyBuilder I need to add custom attributes. However, the API I'm trying to create is abstracting as much reflection stuff as possible so in order to add attributes to types or properties the user supplies an actual attribute.
But as attributes can't be added to TypeBuilder or PropertyBuilder (as far as I've found) I need to create instances of CustomAttributeBuilder (which can be added) with matching values from the supplied attributes. I use the below method to do this and it works fine except for when an attribute has a nullable property.
If an attribute contains a nullable property an ArgumentException is thrown saying "An invalid type was used as a custom attribute constructor argument, field or property." when the last line of the method is executed.
private static CustomAttributeBuilder CreateAttributeWithValuesFromTemplate(
Attribute attribute)
{
var propertiesWithValues = new List<PropertyInfo>();
var nonNullPropertyValues = new List<Object>();
if (attribute != null)
{
var properties = GetWritableProperties(attribute);
object[] propertyValues = GetPropertyValues(attribute, properties);
for (int i = 0; i < properties.Length; i++)
{
if (propertyValues[i] == null)
continue;
propertiesWithValues.Add(properties[i]);
nonNullPropertyValues.Add(propertyValues[i]);
}
}
ConstructorInfo constructor;
if (attributeSpecification.Constructor != null)
constructor = attributeSpecification.Constructor;
else
constructor = attributeSpecification.Type.GetConstructor(new Type[] { });
object[] constructorParams;
if (attributeSpecification.Constructor != null)
constructorParams = attributeSpecification.ConstructorParameters;
else
constructorParams = new object[] {};
return new CustomAttributeBuilder(constructor, constructorParams,
propertiesWithValues.ToArray(), nonNullPropertyValues.ToArray());
}
I've tried to modify the method to check if a property is of a nullable type but I haven't found a way to actually supply a value that is nullable, ie the below code (which is just a test) doesn't work as nullableValue.GetType() will return Int32.
if(properties[i].PropertyType.IsGenericType
&& properties[i].PropertyType.GetGenericTypeDefinition()== typeof(Nullable<>)) {
Nullable<int> nullableValue = new Nullable<int>();
nonNullPropertyValues.Add(nullableValue);
} else {
nonNullPropertyValues.Add(propertyValues[i]);
}
Any solutions or pointers in the right direction would be appreciated.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你为什么不检查财产,而不是价值。
在 GetWritableProperties 中,您可以获取 PropertyInfo 集合。
您可以立即获取属性和值,如下所示:
创建一个类来保存 PropertyInfo 和 Value
,然后将方法 GetWritableProperties 更改为:
这样你就可以节省大量代码。
why dont you check the property, not the value.
Inside your GetWritableProperties where you are getting The PropertyInfo collection.
You can at once get the properties and values like this:
creat a class to hold the PropertyInfo and Value
then change your method GetWritableProperties to:
With this you save alot of code.