Согласно книге, которую я читаю, публичное свойство AllowMultiple
AttributeUsage
указывает:
... может ли цель иметь несколько экземпляров применяемого к ней атрибута.
Почему я хочу/не хочу использовать это?
Согласно книге, которую я читаю, публичное свойство AllowMultiple
AttributeUsage
указывает:
... может ли цель иметь несколько экземпляров применяемого к ней атрибута.
Почему я хочу/не хочу использовать это?
Атрибуты - это метаданные. Как правило, вы хотите украсить элемент или ввести атрибут, чтобы отслеживать некоторую информацию об этом.
Например, атрибут 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
{
// ...
Этот пример может быть немного надуманным, но, надеюсь, он имеет смысл.
[Convertable(typeof(Int32)), Convertable(typeof(Double))]
public class Test
{
}
Это зависит от атрибутов.
Например, вы можете сделать атрибут, который помечает класс как зависящий от чего-то, и вы можете разрешить несколько зависимостей.
Для конкретного примера посмотрите SuppressMessage
, который подавляет предупреждение анализа кода. Член может иметь несколько предупреждений, которые вы, возможно, захотите подавить.
Другим примером является WebResource
; сборка может содержать несколько ресурсов.
Никакого надуманного примера здесь, я использовал его в реальном производственном коде. Я написал некоторый код для анализа файла, содержащего пары данных типа (code = value). Я помещаю пользовательский атрибут в функцию, чтобы указать, что он должен быть вызван для заданного кода.
[CanParseCode("G1")]
[CanParseCode("G2")]
private void ParseGXCodes(string code, string value)
{
...
}
Этот конкретный формат является несколько старым и специфичным для домена с сотнями разных кодов. Моя цель состояла в том, чтобы написать структуру, упрощающую запись файловых процессоров, которые могли бы извлекать только нужные ему коды и игнорировать остальные. Разрешая один и тот же атрибут несколько раз, он упростил выражение намерения кода, просто объявив атрибуты функций (функций), обрабатывающих каждый код.
Применение атрибута 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 "сломал этот шаблон", одновременно отображая две разные коллекции (создает две вкладки и показывает одну пользовательскую коллекцию на одной вкладке, а другую на второй вкладке). Таким же образом представление может обрабатывать две разные пользовательские коллекции. Словарь, представление которого может обрабатывать, какие типы коллекций затем обрабатываются с помощью метода расширения, чтобы позволить любой из наших пользовательских коллекций запускать зарегистрированное представление (или по умолчанию, если нет "зарегистрированного" представления) через одну строку вызовите диспетчер представлений.