При создании типов и свойств с TypeBuilder и PropertyBuilder мне нужно добавить пользовательские атрибуты. Тем не менее, API, который я пытаюсь создать, абстрагирует как можно больше отражений, чтобы добавить атрибуты к типам или свойствам, которые пользователь предоставляет фактическим атрибутом.
Но поскольку атрибуты не могут быть добавлены в TypeBuilder или PropertyBuilder (насколько я обнаружил), мне нужно создать экземпляры CustomAttributeBuilder (которые можно добавить) с соответствующими значениями из предоставленных атрибутов. Для этого я использую приведенный ниже метод, и он работает нормально, за исключением случаев, когда атрибут имеет свойство, допускающее значение 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]);
}
Будем благодарны за любые решения или указатели в правильном направлении.