Самые полезные атрибуты

Я знаю, что атрибуты очень полезны. Есть несколько предопределенных, например [Browsable(false)], который позволяет скрывать свойства на вкладке свойств. Вот хороший вопрос, объясняющий атрибуты: Что такое атрибуты в .NET?

Какие стандартные атрибуты (и их пространство имен) вы фактически используете в своих проектах?


person Community    schedule 28.09.2008    source источник
comment
Что за вопрос? , вся страница переполнена красивыми ответами с замечательными объяснениями. Пока я читаю это, я получил опыт, например, опросил многих экспертов по поводу их взглядов. +100 за вопрос.   -  person Muthu Ganapathy Nathan    schedule 07.05.2013
comment
Я согласен, подобные вопросы - одни из самых ценных - они делают SO менее полезным, что закрываются.   -  person David Thielen    schedule 19.04.2020


Ответы (32)


[DebuggerDisplay] может быть действительно полезным для быстрого просмотра настроенного вывода типа при наведении указателя мыши на экземпляр типа во время отладки. пример:

[DebuggerDisplay("FirstName={FirstName}, LastName={LastName}")]
class Customer
{
    public string FirstName;
    public string LastName;
}

Вот так это должно выглядеть в отладчике:

alt text

Также стоит упомянуть, что атрибут [WebMethod] с установленным свойством CacheDuration может избежать ненужного выполнения метода веб-службы.

person Community    schedule 28.09.2008
comment
Вау, это действительно хорошо знать. Обычно я делал то же самое, переопределив ToString, но это лучше. - person Brian; 16.09.2009
comment
Будьте осторожны, он откусывает гораздо больший кусок вашего процессора, чем ToString. - person Nikola Radosavljević; 22.11.2011
comment
Вы также можете использовать это для отображения результатов методов. Это может вызвать затруднения при отладке, если метод (или свойство get) имеет побочные эффекты. - person Øyvind Skaar; 25.10.2012
comment
@ NikolaRadosavljević будет ли он потреблять мощность процессора только во время отладки - person Nickolay Kondratyev; 17.02.2013
comment
@ Николай Кондратьев: Я не знаю всех тонкостей, но вы можете взглянуть на следующие передовые практики веб-сервисов, которые помогут вам сделать некоторые выводы: blogs.msdn.com/b/jaredpar/archive/2011/03/18/ - person Nikola Radosavljević; 18.02.2013
comment
@Nikola: там говорится только о производительности отладки. - person Per Lundberg; 07.10.2013
comment
Каждый раз, когда у вас есть curly, оценивается внутренняя часть, на что тратится центральный процессор, 2x curly равняется 2x вызовам eval, поэтому чрезмерное количество вызовов может стоить много ресурсов процессора (fx. Показывает длинный список элементов). обходной путь к этому - вызов {DebuggerDisplay()}, который является только одним дорогостоящим вызовом, и вы можете заставить этот метод возвращать все имена свойств, которые вам нужны. Также, если метод является частным, он технически нигде не используется и будет удален во время сборки Release. но отладчик все еще может использовать его во время отладки. - person Jim Wolff; 08.10.2018

System.Obsolete - один из самых полезных атрибутов в структуре, в мое мнение. Возможность выдавать предупреждение о коде, который больше не следует использовать, очень полезна. Мне нравится иметь способ сказать разработчикам, что что-то больше не следует использовать, а также иметь способ объяснить, почему и указать на лучший / новый способ что-то делать.

Conditional attribute также очень удобен для отладки. Это позволяет вам добавлять методы в ваш код для целей отладки, которые не будут скомпилированы, когда вы создадите свое решение для выпуска.

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

person Community    schedule 28.09.2008
comment
Мне нравится флаг устаревшего, но он просто вызывает предупреждение. Большинство людей, с которыми я столкнулся, игнорируют предупреждения в VS - person wusher; 02.10.2008
comment
Да, я тоже это заметил. Я работал над приложениями, где есть сотни предупреждений. Большинство из них нужно было исправить, но не по какой-то причине. Я никогда этого не понимал ... - person Dan Herbert; 04.10.2008
comment
Вы можете передать true в качестве одного из параметров System.Obsolete, что приведет к тому, что предупреждение станет ошибкой, что приведет к нарушению сборки. Очевидно, это следует сделать после того, как вы удалите все предупреждения. :) - person Adrian Clark; 01.12.2008
comment
После того, как вы очистите все предупреждения, не лучше ли просто удалить метод? - person Pedro; 16.01.2009
comment
@Pedro: Иногда нельзя по причинам обратной совместимости. Если он частный и неиспользуемый, да, удалите его. - person Fantius; 02.06.2009
comment
В отношении Obsolete следует отметить одну вещь: вы всегда можете обойти ошибку компиляции, обратившись к методу через отражение. Даже с ошибкой компиляции лучше также добавить метод, если вам нужно его оставить. - person plinth; 16.09.2009
comment
@plinth Создание исключения было бы плохой идеей по многим причинам. №1 заключается в том, что основная причина использования Obsolete () заключается в том, чтобы вы могли продолжать работу скомпилированного кода во время переходной фазы. Если вы не разрешаете никому вызывать метод, почему бы просто не удалить его? - person Dan Herbert; 16.09.2009
comment
@Dan - если вы помечаете Obsolete ошибкой с ошибкой при компиляции, то он не должен когда-либо вызываться. Если он вызывается во время выполнения, значит кто-то нарушил Устаревший ... - person plinth; 16.09.2009
comment
@plinth Это сделано для предотвращения использования метода новым кодом. Старый код останется двоично-совместимым, если метод помечен как устаревший, но он перестанет работать, если вы создадите исключение. Если кто-то использует отражение, чтобы обойти флаг Obsolte, то у вас проблемы похуже ... - person Dan Herbert; 16.09.2009
comment
Недавно я написал статью об использовании условных атрибутов для отладки. На самом деле мне нравится использовать их больше, чем точки останова в определенных случаях. Вот несколько примеров ... codefromjames.com/wordpress/?p=131 - person jocull; 23.08.2012
comment
Если вы выпускаете свои библиотеки DLL как API с поддержкой версий, вы можете сохранить метод устаревших ошибок, чтобы люди могли получить информацию о том, почему он больше не работает, а не о том, что метод просто не существует. [Obsolete( "Use X instead", true )] указывает причину, по которой код не компилируется, и предлагает альтернативу. - person Tarka; 22.06.2017

[Flags] очень удобен. Синтаксический сахар, конечно, но все же довольно приятный.

[Flags] 
enum SandwichStuff
{
   Cheese = 1,
   Pickles = 2,
   Chips = 4,
   Ham = 8,
   Eggs = 16,
   PeanutButter = 32,
   Jam = 64
};

public Sandwich MakeSandwich(SandwichStuff stuff)
{
   Console.WriteLine(stuff.ToString());
   // ...
}

// ...

MakeSandwich(SandwichStuff.Cheese 
   | SandwichStuff.Ham 
   | SandwichStuff.PeanutButter);
// produces console output: "Cheese, Ham, PeanutButter"

Леппи указывает на то, что я не осознавал, и что несколько ослабляет мой энтузиазм по поводу этого атрибута: он не инструктирует компилятор разрешать битовые комбинации в качестве допустимых значений для переменных перечисления. , компилятор позволяет это для перечислений независимо. Мой фон C ++ просвечивает ... вздох

person Community    schedule 28.09.2008
comment
Итак, что именно делает атрибут Flags? - person Andrei Rînea; 28.09.2008
comment
Я думаю, что перечисление должно наследовать от int, не так ли? - person Martin Clarke; 28.09.2008
comment
@Andrei: превращает тип перечисления в тип битового поля с поддерживающими метаданными. - person Shog9; 28.09.2008
comment
@Martin: int - это тип по умолчанию; если вам нужно что-то еще, вы бы это указали. - person Shog9; 28.09.2008
comment
Я надеюсь, вы, ребята, понимаете, что атрибут Flags делает все возможное. Он вообще не нужен / не используется, кроме TypeConverter. - person leppie; 13.10.2008
comment
@leppie: ToString () тоже. Но ... вау. По какой-то причине я ожидал, что поведение перечислений без атрибута будет таким же, как в C ++: значения or'd производят целое число (не могут быть переданы как есть методу, ожидающему параметра enum). Теперь я понимаю, что это не так. Слабый ... хорошо, перечисления .NET - отстой. - person Shog9; 13.10.2008
comment
[Flags] действительно только помогает отладчику и функциям .ToString () знать, что значение потенциально является комбинацией нескольких объявлений в перечислении. Я не уверен, может ли Intellisense помочь вам более эффективно использовать перечисление. - person Kenzi; 18.02.2012
comment
[Flags] действительно имеет большее применение, чем просто синтаксический сахар. При использовании веб-сервисов сериализация / десериализация не будет работать, если будет передано значение типа SandwichStuff.Cheese | SandwichStuff.Ham | SandwichStuff.Jam. Без атрибута [Flags] десериализатор не узнает, что значение может быть комбинацией флагов. Я усвоил это на собственном горьком опыте, потратив около двух дней на размышления, почему мой WCF не работает. - person Anchit; 20.07.2012
comment
@leppie следует использовать атрибут flags, чтобы указать, что вы можете использовать побитовое ИЛИ. Использование его в перечислениях, которые не отмечены им, вероятно, не будет в степени 2, что приведет к беспорядку. - person Alexander; 02.05.2019

Мне нравится [DebuggerStepThrough] из System.Diagnostics.

Это очень удобно, чтобы избежать использования однострочных методов или свойств, которые ничего не делают (если вы вынуждены работать в раннем .Net без автоматических свойств). Поместите атрибут в короткий метод или в средство получения или установки свойства, и вы пролетите мимо, даже нажав «шаг в» в отладчике.

person Community    schedule 28.09.2008
comment
Сколько раз я хотел знать об этой собственности - person wusher; 28.09.2008
comment
Жаль, что он сломан закрытием - см. gregbeech.com/blogs/tech/archive/2008/10/17/ для получения дополнительной информации. - person Greg Beech; 01.12.2008
comment
Также полезно для любого кода WM_Paint, который, как вы знаете, работает :) - person Pondidum; 02.05.2009
comment
@GregBeech Этот URL возвращает ошибку .NET. Классно! :) - person smdrager; 08.06.2012
comment
@smdrager - Должно быть, это временная проблема, похоже, сегодня у меня работает. - person Greg Beech; 17.06.2012
comment
[DebuggerHidden] - еще один хороший. Это заставляет выброшенные ошибки прерываться в вызывающем методе (для таких вещей, как обработчики БД) - person Patrick; 02.12.2014

Как бы то ни было, вот список всех атрибутов .NET . Их несколько сотен.

Я не знаю ни о ком другом, но мне нужно серьезно заняться RTFM!

person Community    schedule 28.09.2008
comment
Обновил ссылку в вопросе. Теперь это полный список для 3.5 - person R. Martinho Fernandes; 08.11.2009
comment
Собственно то ссылки на последнюю, а не на 3.5 конкретно. - person Brian Ortiz; 27.06.2010
comment
Вот если бы список был не просто списком ссылок, а именем и описанием. Ну что ж. @BrianOrtiz прав. Список находится в версии 4.5. - person Luminous; 10.09.2014
comment
Вы просто меняете целевую платформу вверху, где написано «Другие версии». - person Novaterata; 06.02.2015
comment
msdn.microsoft.com/en-us / library /, чтобы увидеть гораздо больший и более свежий список. - person MathuSum Mut; 19.02.2017

Я бы проголосовал за Conditional

[Conditional("DEBUG")]
public void DebugOnlyFunction()
{
    // your code here
}

Вы можете использовать это, чтобы добавить функцию с расширенными функциями отладки; как и Debug.Write, он вызывается только в отладочных сборках и поэтому позволяет вам инкапсулировать сложную логику отладки вне основного потока вашей программы.

person Community    schedule 21.05.2009
comment
Разве это не то же самое, что делать #if DEBUG? - person Neil N; 11.08.2009
comment
В некотором смысле, #if DEBUG означает, что вызывающий объект также не должен вызывать его, в то время как Conditioinal оставляет вызов, но делает его NOP, который удаляется при JIT. - person Rangoric; 14.03.2011
comment
Кроме того, вы обычно используете #if DEBUG вокруг вызовов и [Conditional] вокруг методов. Поэтому, если вы вызываете метод отладки 100 раз, его отключение зависит от одного изменения кода, а не 100 раз. - person Steve Cooper; 15.03.2011
comment
Комментарий Рангорика несколько неверен (по крайней мере, для C #): метод включен без изменений; сам сайт вызова опускается. Это имеет несколько последствий: параметры не оцениваются, а условный метод содержится в выводе компилятора без изменений. Вы можете убедиться в этом с помощью рефлексии. msdn.microsoft.com/en-us/library/aa664622.aspx blogs.msdn .com / b / jmstall / archive / 2007/10/15 / - person Mark Sowul; 03.10.2012

Я всегда использую атрибуты DisplayName, Description и DefaultValue поверх общедоступных свойств моих пользовательских элементов управления, настраиваемых элементов управления или любого класса, который я редактирую через сетку свойств. Эти теги используются .NET PropertyGrid для форматирования имени, панели описания и значений, выделенных жирным шрифтом, для которых не заданы значения по умолчанию.

[DisplayName("Error color")]
[Description("The color used on nodes containing errors.")]
[DefaultValue(Color.Red)]
public Color ErrorColor
{
    ...
} 

Я просто хочу, чтобы IntelliSense в Visual Studio учла атрибут Description, если XML-комментарий не найден. Это позволило бы избежать повторения одного и того же предложения дважды.

person Community    schedule 12.03.2009
comment
Не могу поверить, что никто не указал Description, пока вы .. Это наиболее полезно для меня, когда используется с перечислениями .. - person nawfal; 09.06.2013

[Serializable] постоянно используется для сериализации и десериализации объектов во внешние источники данных, такие как xml или с удаленного сервера, и из них. Подробнее об этом здесь.

person Community    schedule 28.09.2008
comment
Фактически это называется псевдоатрибутом, поскольку C # выдает флаг метаданных для [Serializable], а не экземпляр настраиваемого атрибута;) - person TraumaPony; 28.09.2008
comment
Хотя [Serializable] очень полезен, он далек от совершенства. Чтобы получить желаемый результат, требуется слишком много усилий, проб и ошибок. - person shoosh; 04.01.2009
comment
Я поддержу это шиш! - person John B; 15.04.2009
comment
System.NonSerializedAttribute полезен, если вам нужен больший контроль над автоматической сериализацией. - person CSharper; 29.04.2009
comment
В качестве примечания я бы добавил, что производительность встроенной сериализации .Net довольно низкая, примерно на 2 или 3 порядка медленнее, чем код, созданный вручную. - person redcalx; 13.01.2010

В духе Хофштадта атрибут [Attribute] очень полезен, поскольку с его помощью вы создаете свои собственные атрибуты. Я использовал атрибуты вместо интерфейсов для реализации систем плагинов, добавления описаний в Enums, имитации множественной диспетчеризации и других трюков.

person Community    schedule 28.09.2008
comment
Звучит круто! Не могли бы вы показать несколько примеров системы плагинов и описаний перечислений? Я заинтересован в том, чтобы реализовать обе эти вещи! - person John B; 15.04.2009

Вот сообщение об интересном атрибуте InternalsVisibleTo. В основном то, что он делает, он имитирует функциональность доступа друзей C ++. Это очень удобно для модульного тестирования.

person Community    schedule 02.05.2009
comment
Разве вы не имеете в виду удобство для взлома модульного теста на то, что нельзя / не нужно тестировать? - person the_drow; 13.07.2011
comment
@the_drow: Вы говорите о «частных аксессуарах»: msdn.microsoft.com/en-us/library/ms184807%28v=vs.80%29.aspx - person habakuk; 12.07.2012
comment
@habakuk: Не совсем. Есть случаи, когда внутренние классы должны быть представлены для модульного тестирования, обычно из-за плохого дизайна. - person the_drow; 12.07.2012
comment
@the_drow: Я бы не сказал, что InternalsVisibleTo вреден для модульного тестирования; вы можете создавать и тестировать меньшие единицы, которые не видны за пределами вашего проекта (это помогает вам иметь чистый и небольшой api). Но если вам нужны «частные аксессоры» для модульного тестирования, то, вероятно, что-то не так. - person habakuk; 13.07.2012
comment
@habakuk: Если его нужно протестировать, то он должен быть общедоступным. - person the_drow; 13.07.2012
comment
@the_drow Я не согласен с вашим утверждением, что internal не является публичным. Он общедоступен в тестируемой сборке и должен проходить модульное тестирование, чтобы другие классы в сборке могли предположить, что это функция исправления. Если вы его не тестируете, вам придется протестировать его функции во всех потребляющих классах. - person tvanfosson; 10.12.2012

Я нашел [DefaultValue] весьма полезным.

person Community    schedule 28.09.2008

Я бы предложил [TestFixture] и [Test] - из библиотеки nUnit.

Модульные тесты в вашем коде обеспечивают безопасность при рефакторинге и кодифицированной документации.

person Community    schedule 28.09.2008

[XmlIgnore]

поскольку это позволяет игнорировать (в любой сериализации xml) «родительские» объекты, которые в противном случае могли бы вызвать исключения при сохранении.

person Community    schedule 15.10.2008

Он плохо назван, плохо поддерживается в фреймворке и не требует параметра, но этот атрибут является полезным маркером для неизменяемых классов:

[ImmutableObject(true)]
person Community    schedule 09.06.2009
comment
Согласно документации, используется только во время разработки (к сожалению). - person Hans Kesting; 16.09.2009
comment
Учитывая, что это только время разработки, возможно, было бы лучше создать свой собственный класс ImmutableObjectAttribute - по крайней мере, вы могли бы исключить параметр. - person Roy Tinker; 05.03.2014

Мне нравится использовать атрибут [ThreadStatic] в сочетании с программированием на основе потоков и стека. Например, если мне нужно значение, которым я хочу поделиться с остальной частью последовательности вызовов, но я хочу сделать это вне диапазона (т.е. вне параметров вызова), я могу использовать что-то вроде этого.

class MyContextInformation : IDisposable {
    [ThreadStatic] private static MyContextInformation current;

    public static MyContextInformation Current {
        get { return current; }
    }

    private MyContextInformation previous;


    public MyContextInformation(Object myData) {
       this.myData = myData;
       previous = current;
       current = this;
    }

    public void Dispose() {
       current = previous;
    }
}

Позже в своем коде я могу использовать это для внеполосного предоставления контекстной информации людям, находящимся ниже по течению от моего кода. Пример:

using(new MyContextInformation(someInfoInContext)) {
   ...
}

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

person Community    schedule 01.12.2008
comment
а как тогда получить доступ? Не понимаю смысла вашего образца использования здесь. Вы можете объяснить? - person Beachwalker; 21.08.2015
comment
@Beachwalker Current должен быть статическим, отредактировал его сейчас. Теперь вы можете получить доступ к MyContextInformation.Current, чтобы получить активный контекст в стеке. Это то, что является очень хорошей концепцией в определенных случаях, наш (моей компании) движок использует ее для множества целей. - person Felix K.; 04.01.2016

DebuggerHiddenAttribute, который позволяет избежать входа в код, который не надо отлаживать.

public static class CustomDebug
{
    [DebuggerHidden]
    public static void Assert(Boolean condition, Func<Exception> exceptionCreator) { ... }
}

...

// The following assert fails, and because of the attribute the exception is shown at this line
// Isn't affecting the stack trace
CustomDebug.Assert(false, () => new Exception()); 

Также он предотвращает отображение методов в трассировке стека, что полезно при наличии метода, который просто обертывает другой метод:

[DebuggerHidden]
public Element GetElementAt(Vector2 position)
{
    return GetElementAt(position.X, position.Y);
}

public Element GetElementAt(Single x, Single y) { ... }

Если теперь вы вызываете GetElementAt(new Vector2(10, 10)) и в обернутом методе возникает ошибка, стек вызовов не показывает метод, который вызывает метод, который вызывает ошибку.

person Community    schedule 05.12.2012

DesignerSerializationVisibilityAttribute очень полезен. Когда вы помещаете свойство среды выполнения в элемент управления или компонент и не хотите, чтобы дизайнер сериализовал его, вы используете его следующим образом:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Foo Bar {
    get { return baz; }
    set { baz = value; }
}
person Community    schedule 04.01.2009
comment
очень полезно для компонентов WinForms. использовать вместе с [Browsable (false)] - person Mark Heath; 09.11.2010
comment
Хороший момент - [Browsable(false)] требуется, чтобы скрыть его от пользователя дизайнера, где [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] требуется, чтобы он не был сериализован. - person configurator; 09.11.2010

Компилятор поддерживает только несколько атрибутов, но одно очень интересное использование атрибутов находится в АОП: PostSharp использует ваши индивидуальные атрибуты. внедрять IL в методы, обеспечивая всевозможные возможности ... log / trace - это тривиальные примеры, но некоторые другие хорошие примеры - это такие вещи, как автоматическая реализация INotifyPropertyChanged (здесь).

Некоторые из них возникают и напрямую влияют на компилятор или среду выполнения:

  • [Conditional("FOO")] - вызовы этого метода (включая оценку аргументов) происходят только в том случае, если во время сборки определен символ "FOO"
  • [MethodImpl(...)] - используется для обозначения некоторых вещей, таких как синхронизация, встраивание
  • [PrincipalPermission(...)] - используется для автоматической вставки проверок безопасности в код
  • [TypeForwardedTo(...)] - используется для перемещения типов между сборками без перестройки вызывающих

Для вещей, которые проверяются вручную через отражение - я большой поклонник атрибутов System.ComponentModel; такие вещи, как [TypeDescriptionProvider(...)], [TypeConverter(...)] и [Editor(...)], которые могут полностью изменить поведение типов в сценариях привязки данных (например, динамические свойства и т. д.).

person Community    schedule 29.09.2008

Если бы я выполнял сканирование покрытия кода, я думаю, что эти два были бы лучшими:

 [Serializable]
 [WebMethod]
person Community    schedule 28.09.2008
comment
[WebMethod] используется для украшения метода, предоставляемого веб-службой. [Serializable] помечает ваши объекты так, чтобы их можно было сериализовать для таких целей, как передача их между доменами приложений. - person Kev; 28.09.2008

В последнее время я использую [DataObjectMethod]. Он описывает метод, поэтому вы можете использовать свой класс с ObjectDataSource (или другими элементами управления).

[DataObjectMethod(DataObjectMethodType.Select)] 
[DataObjectMethod(DataObjectMethodType.Delete)] 
[DataObjectMethod(DataObjectMethodType.Update)] 
[DataObjectMethod(DataObjectMethodType.Insert)] 

Дополнительная информация

person Community    schedule 15.10.2008

В нашем текущем проекте мы используем

[ComVisible(false)]

Он контролирует доступность отдельного управляемого типа или члена или всех типов в сборке для COM.

Дополнительная информация

person Community    schedule 22.10.2008

[TypeConverter(typeof(ExpandableObjectConverter))]

Сообщает дизайнеру расширить свойства, которые являются классами (вашего контроля)

[Obfuscation]

Дает указание средствам обфускации выполнять указанные действия для сборки, например, или член. (Хотя обычно вы используете уровень сборки [assembly:ObfuscateAssemblyAttribute(true)]

person Community    schedule 13.10.2008
comment
Я догадался, но ошибся. Атрибут обфускации - это всего лишь подсказка для сторонних обфсукаторов. Это не заставляет компилятор что-либо скрывать по умолчанию. - person Dan Is Fiddling By Firelight; 04.01.2012
comment
@DanNeely бесплатно для пользователей Visual Studio Pro / Ultimate! - person Chris S; 04.01.2012
comment
Если вы имеете в виду DotFuscator Community Edition, уровень защиты настолько низок, что в лучшем случае он почти ни для чего не учитывается. - person Dan Is Fiddling By Firelight; 04.01.2012
comment
@ricovox Я добавил резюме - person Chris S; 03.01.2013

Чаще всего я использую атрибуты, связанные с сериализацией XML.

XmlRoot

XmlElement

XmlAttribute

и т.д...

Чрезвычайно полезно при выполнении любого быстрого и грязного синтаксического анализа или сериализации XML.

person Community    schedule 28.09.2008

Как разработчик среднего уровня мне нравится

System.ComponentModel.EditorBrowsableAttribute Позволяет мне скрывать свойства, чтобы разработчик пользовательского интерфейса не был перегружен свойствами, которые им не нужно видеть.

System.ComponentModel.BindableAttribute Некоторые вещи не нужно связывать с данными. Опять же, сокращает объем работы, необходимой разработчикам пользовательского интерфейса.

Мне также нравится DefaultValue, о котором упоминал Лоуренс Джонстон.

System.ComponentModel.BrowsableAttribute и Flags используются регулярно.

При необходимости использую System.STAThreadAttribute System.ThreadStaticAttribute.

Кстати. Я не менее ценен для всех разработчиков фреймворка .Net.

person Community    schedule 28.09.2008

[EditorBrowsable(EditorBrowsableState.Never)] позволяет скрыть свойства и методы от IntelliSense, если проект отсутствует в вашем решении. Очень полезно для сокрытия недопустимых потоков для свободных интерфейсов. Как часто вы хотите использовать GetHashCode () или Equals ()?

Для MVC [ActionName("Name")] позволяет вам иметь действия Get и Post с одной и той же сигнатурой метода или использовать тире в имени действия, что в противном случае было бы невозможно без создания для него маршрута.

person Community    schedule 08.06.2012

Я считаю важным упомянуть здесь, что следующие атрибуты также очень важны:

STAThreadAttribute 

Указывает, что модель потоков COM для приложения является однопоточным подразделением (STA).

Например, этот атрибут используется в приложениях Windows Forms:

static class Program
{
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}

А также ...

SuppressMessageAttribute

Подавляет сообщение о конкретном нарушении правил инструмента статического анализа, разрешая множественное подавление одного артефакта кода.

Например:

[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "isChecked")]
[SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "fileIdentifier")]
static void FileNode(string name, bool isChecked)
{
    string fileIdentifier = name;
    string fileName = name;
    string version = String.Empty;
}
person Community    schedule 15.10.2012
comment
Используется ли STAThread для предотвращения случайного запуска вашего приложения другим экземпляром самого себя при запуске? - person Luminous; 10.09.2014

Внезапно, вот краткий список, примерно отсортированный по частоте использования, предопределенных атрибутов, которые я действительно использую в большом проекте (~ 500k LoC):

Флаги, Сериализуемый, WebMethod, COMVisible, TypeConverter, Conditional, ThreadStatic, Obsolete, InternalsVisibleTo, DebuggerStepThrough.

person Community    schedule 11.03.2012
comment
+1 за ThreadStatic, удивлен, что никто об этом пока не упомянул, а также за статистический подход - person staafl; 01.10.2013

Я генерирую класс сущности данных через CodeSmith и использую атрибуты для некоторой процедуры проверки. Вот пример:

/// <summary>
/// Firm ID
/// </summary>
[ChineseDescription("送样单位编号")]
[ValidRequired()]
public string FirmGUID
{
    get { return _firmGUID; }
    set { _firmGUID = value; }
}

И у меня есть служебный класс для проверки на основе атрибутов, прикрепленных к классу сущности данных. Вот код:

namespace Reform.Water.Business.Common
{
/// <summary>
/// Validation Utility
/// </summary>
public static class ValidationUtility
{
    /// <summary>
    /// Data entity validation
    /// </summary>
    /// <param name="data">Data entity object</param>
    /// <returns>return true if the object is valid, otherwise return false</returns>
    public static bool Validate(object data)
    {
        bool result = true;
        PropertyInfo[] properties = data.GetType().GetProperties();
        foreach (PropertyInfo p in properties)
        {
            //Length validatioin
            Attribute attribute = Attribute.GetCustomAttribute(p,typeof(ValidLengthAttribute), false);
            if (attribute != null)
            {
                ValidLengthAttribute validLengthAttribute = attribute as ValidLengthAttribute;
                if (validLengthAttribute != null)
                {
                    int maxLength = validLengthAttribute.MaxLength;
                    int minLength = validLengthAttribute.MinLength;
                    string stringValue = p.GetValue(data, null).ToString();
                    if (stringValue.Length < minLength || stringValue.Length > maxLength)
                    {
                        return false;
                    }
                }
            }
            //Range validation
            attribute = Attribute.GetCustomAttribute(p,typeof(ValidRangeAttribute), false);
            if (attribute != null)
            {
                ValidRangeAttribute validRangeAttribute = attribute as ValidRangeAttribute;
                if (validRangeAttribute != null)
                {
                    decimal maxValue = decimal.MaxValue;
                    decimal minValue = decimal.MinValue;
                    decimal.TryParse(validRangeAttribute.MaxValueString, out maxValue);
                    decimal.TryParse(validRangeAttribute.MinValueString, out minValue);
                    decimal decimalValue = 0;
                    decimal.TryParse(p.GetValue(data, null).ToString(), out decimalValue);
                    if (decimalValue < minValue || decimalValue > maxValue)
                    {
                        return false;
                    }
                }
            }
            //Regex validation
            attribute = Attribute.GetCustomAttribute(p,typeof(ValidRegExAttribute), false);
            if (attribute != null)
            {
                ValidRegExAttribute validRegExAttribute = attribute as ValidRegExAttribute;
                if (validRegExAttribute != null)
                {
                    string objectStringValue = p.GetValue(data, null).ToString();
                    string regExString = validRegExAttribute.RegExString;
                    Regex regEx = new Regex(regExString);
                    if (regEx.Match(objectStringValue) == null)
                    {
                        return false;
                    }
                }
            }
            //Required field validation
            attribute = Attribute.GetCustomAttribute(p,typeof(ValidRequiredAttribute), false);
            if (attribute != null)
            {
                ValidRequiredAttribute validRequiredAttribute = attribute as ValidRequiredAttribute;
                if (validRequiredAttribute != null)
                {
                    object requiredPropertyValue = p.GetValue(data, null);
                    if (requiredPropertyValue == null || string.IsNullOrEmpty(requiredPropertyValue.ToString()))
                    {
                        return false;
                    }
                }
            }
        }
        return result;
    }
}
}
person Community    schedule 22.11.2011

[DeploymentItem("myFile1.txt")] Документ MSDN по DeploymentItem

Это действительно полезно, если вы тестируете файл или используете файл в качестве входных данных для вашего теста.

person Community    schedule 16.09.2009

[System.Security.Permissions.PermissionSetAttribute] позволяет применять меры безопасности для PermissionSet к коду с использованием декларативной безопасности.

// usage:
public class FullConditionUITypeEditor : UITypeEditor
{
    // The immediate caller is required to have been granted the FullTrust permission.
    [PermissionSetAttribute(SecurityAction.LinkDemand, Name = "FullTrust")]
    public FullConditionUITypeEditor() { }
}
person Community    schedule 29.04.2009

Я всегда использую атрибуты [Serializable], [WebMethod], [DefaultValue], [Description("description here")].

но кроме этого есть Глобальные атрибуты в c #.

[assembly: System.CLSCompliant(true)]
[assembly: AssemblyCulture("")]
[assembly: AssemblyDescription("")]
person Community    schedule 17.09.2012

person    schedule
comment
какова цель NotifyParentProperty? - person Maslow; 05.01.2012