С#: Какая разница между TypeDescriptor.GetAttributes() и GetType().GetCustomAttributes?
Возьмите эти две вещи кода:
instance.GetType()
.GetCustomAttributes(true)
.Where(item => item is ValidationAttribute);
и
TypeDescriptor.GetAttributes(instance)
.OfType<ValidationAttribute>();
Если класс выглядит следующим образом:
[RequiredIfOtherPropertyIsNotEmpty("State", "City", ErrorMessage = ErrorDescription.CreateAccount_CityRequiredWithState)]
[RequiredIfOtherPropertyIsNotEmpty("State", "Address1", ErrorMessage = ErrorDescription.CreateAccount_Address1RequiredWithState)]
public class ManagePostModel
{
...
}
Где RequiredIfOtherPropertyIsNotEmpty
есть ValidationAttribute
и имеет AllowMultiple = true
.
Первый возвращает два атрибута, второй возвращает один.
Какая разница, которая может вызвать это?
Ответы
Ответ 1
От страница MSDN в TypeDescriptor.GetAttributes:
Чтобы вернуть несколько экземпляров атрибута AttributeUsageAttribute.AllowMultiple
из AttributeCollection
, ваш атрибут должен переопределить свойство Attribute.TypeId
.
Чтобы ответить на общий вопрос "какая разница?": значения, возвращаемые TypeDescriptor
, могут быть расширены во время выполнения, тогда как те, что указаны в Type
, не могут. Страница MSDN, на которую я ссылался, объясняет больше.
Если вам не требуется такое расширение для выполнения, а способ TypeDescriptor
обрабатывать несколько атрибутов - проблема, вам, вероятно, лучше с Type.GetCustomAttributes
.
Ответ 2
TypeDescriptor просто позволяет расширять тип во время выполнения.
Так, например, если вы хотите добавить атрибут к типу во время выполнения, который вы хотели бы проверить позже, вы должны сделать что-то вроде этого.
TypeDescriptor.AddAttributes(typeToExtend, new SomeAttribute());
Один важный аспект, на который следует обратить внимание, - это тот факт, что к атрибутам, реквизитам и т.д., Добавляемым к типу во время выполнения с помощью TypeDescriptor, можно получить доступ только с использованием TypeDescriptor, а не Type.
Это выкинет исключение
typeToExtend.GetType().GetCustomAttribute<SomeAttribute>()
правильный путь.
AttributeCollection attributes = TypeDescriptor.GetAttributes(typeToExtend);
SomeAttribute attribute = (SomeAttribute)attributes[typeof(SomeAttribute)];