Подтвердить что ты не робот

С#: Какая разница между 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.

Первый возвращает два атрибута, второй возвращает один.

Какая разница, которая может вызвать это?

4b9b3361

Ответ 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)];