Зачем использовать AttributeUsage AllowMultiple при создании атрибутов? - PullRequest
17 голосов
/ 07 января 2010

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

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

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

Ответы [ 5 ]

22 голосов
/ 07 января 2010

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

Например, атрибут 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
{
    // ...
5 голосов
/ 07 января 2010

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

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

}
2 голосов
/ 07 января 2010

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

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

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

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

1 голос
/ 07 января 2010

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

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

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

0 голосов
/ 21 марта 2014

Реальное применение атрибута 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 «нарушил этот шаблон», отображая две разные коллекции одновременно (создает две вкладки и показывает одну настраиваемую коллекцию на одной вкладке, а другую - на второй вкладке). Таким образом, одно и то же представление может обрабатывать две разные настраиваемые коллекции. Словарь того, какие представления способны обрабатывать, какие типы коллекций затем используются с помощью метода расширения, чтобы позволить любой из наших пользовательских коллекций запускать зарегистрированное представление (или представление по умолчанию, если нет «зарегистрированного» представления) через одну строку позвоните менеджеру по просмотру.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...