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

Почему при создании атрибутов нужно использовать AttributeUsage AllowMultiple?

Согласно книге, которую я читаю, публичное свойство AllowMultiple AttributeUsage указывает:

... может ли цель иметь несколько экземпляров применяемого к ней атрибута.

Почему я хочу/не хочу использовать это?

4b9b3361

Ответ 1

Атрибуты - это метаданные. Как правило, вы хотите украсить элемент или ввести атрибут, чтобы отслеживать некоторую информацию об этом.

Например, атрибут DescriptionAttribute используется PropertyGrid для обозначения описания свойства:

[Description("This is my property")]
public int MyProperty { get; set; }

В большинстве случаев наличие более одного описания не имеет смысла.

Однако, возможно, что конкретный атрибут имеет смысл использовать более одного раза. В этом случае вы должны установить Атрибут, чтобы разрешить нескольким экземплярам, ​​помеченным те же атрибуты.

(Не то, чтобы я сделал это, но...) Скажем, вы создали настраиваемый атрибут для отслеживания основных изменений в классе. Вы можете указать это для каждого существенного изменения:

[Changes(Version=1.1, Change="Added Foo Feature")]
[Changes(Version=2.0, Change="Added Bar Feature")]
public class MyClass
{
    // ...

Ответ 2

Этот пример может быть немного надуманным, но, надеюсь, он имеет смысл.

[Convertable(typeof(Int32)), Convertable(typeof(Double))]
public class Test
{

}

Ответ 3

Это зависит от атрибутов.

Например, вы можете сделать атрибут, который помечает класс как зависящий от чего-то, и вы можете разрешить несколько зависимостей.

Для конкретного примера посмотрите SuppressMessage, который подавляет предупреждение анализа кода. Член может иметь несколько предупреждений, которые вы, возможно, захотите подавить.

Другим примером является WebResource; сборка может содержать несколько ресурсов.

Ответ 4

Никакого надуманного примера здесь, я использовал его в реальном производственном коде. Я написал некоторый код для анализа файла, содержащего пары данных типа (code = value). Я помещаю пользовательский атрибут в функцию, чтобы указать, что он должен быть вызван для заданного кода.

[CanParseCode("G1")]
[CanParseCode("G2")]
private void ParseGXCodes(string code, string value)
{
   ...
}

Этот конкретный формат является несколько старым и специфичным для домена с сотнями разных кодов. Моя цель состояла в том, чтобы написать структуру, упрощающую запись файловых процессоров, которые могли бы извлекать только нужные ему коды и игнорировать остальные. Разрешая один и тот же атрибут несколько раз, он упростил выражение намерения кода, просто объявив атрибуты функций (функций), обрабатывающих каждый код.

Ответ 5

Применение атрибута Real World AllowMultiple = истинная полезность

[ManagesType(typeof(SPEC_SEC_OC), true)]
[ManagesType(typeof(SPEC_SEC_04_OC), true)]
public class LibSpecSelectionView : CustomView
{
    public LibSpecSelectionView(SPEC_SEC_OC)
    {}
    public LibSpecSelectionView(SPEC_SEC_O4_OC)
    {}
    ....
}

public static class ViewManager
{
   ...  static Dictionary of views built via reflection
   public void LaunchView(this CollectionBaseClass cbc)
   {
       ... Find class registered to handle cbc type in dictionary and call ctor
   }
}

SPEC_SEC_OC myOC = DataClient.Instance.GetSPEC_SEC_OC();
myOC.LaunchView()

Я перебросил AllowMultiple = true ранее сегодня, чтобы использовать атрибут ManagesType более одного раза. У нас есть несколько сотен классов пользовательской коллекции. Большинство этих пользовательских коллекций имеют представление, которое наследует от CustomView, предназначенного для обработки создания пользовательского интерфейса для определенного типа пользовательской коллекции и представления его пользователю. Атрибут ManagesType используется путем отражения для создания словаря КАЖДОГО просмотра в нашем приложении, которое наследует от CustomView, чтобы "зарегистрировать", какой тип объекта он предназначен для обработки. LibSpecSelectionView "сломал этот шаблон", одновременно отображая две разные коллекции (создает две вкладки и показывает одну пользовательскую коллекцию на одной вкладке, а другую на второй вкладке). Таким же образом представление может обрабатывать две разные пользовательские коллекции. Словарь, представление которого может обрабатывать, какие типы коллекций затем обрабатываются с помощью метода расширения, чтобы позволить любой из наших пользовательских коллекций запускать зарегистрированное представление (или по умолчанию, если нет "зарегистрированного" представления) через одну строку вызовите диспетчер представлений.