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





[Serializable] постоянно используется для сериализации и десериализации объектов во внешние источники данных, такие как xml или с удаленного сервера, и из них. Подробнее об этом здесь.
Фактически это называется псевдоатрибутом, поскольку C# выдает флаг метаданных для [Serializable], а не экземпляр настраиваемого атрибута;)
Хотя [Serializable] очень полезен, он далек от совершенства. Чтобы получить желаемый результат, требуется слишком много усилий, проб и ошибок.
Я поддержу это!
System.NonSerializedAttribute полезен, если вам нужен больший контроль над автоматической сериализацией.
В качестве примечания я бы добавил, что производительность встроенной сериализации .Net довольно низкая, примерно на 2 или 3 порядка медленнее, чем код, созданный вручную.
[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++ просматривается через ... вздох
Итак, что именно делает атрибут Flags?
Я думаю, что перечисление должно наследовать от int, не так ли?
@Andrei: превращает тип перечисления в тип битового поля с поддерживающими метаданными.
@Martin: int - это тип по умолчанию; если вам нужно что-то еще, вы должны это указать.
Я надеюсь, вы, ребята, понимаете, что атрибут Flags делает все возможное. Он вообще не нужен / не используется, кроме TypeConverter.
@leppie: ToString () тоже. Но ... вау. По какой-то причине я ожидал, что поведение перечислений без атрибута будет таким же, как в C++: значения or'd производят целое число (не могут быть переданы как есть методу, ожидающему параметра enum). Теперь я понимаю, что это не так. Слабый ... хорошо, перечисления .NET - отстой.
[Flags] действительно только помогает отладчику и функциям .ToString () знать, что значение потенциально является комбинацией нескольких объявлений в перечислении. Я не уверен, может ли Intellisense помочь вам более эффективно использовать перечисление.
[Flags] имеет большее применение, чем просто синтаксический сахар. При использовании веб-сервисов сериализация / десериализация не будет работать, если будет передано значение вроде SandwichStuff.Cheese | SandwichStuff.Ham | SandwichStuff.Jam. Без атрибута [Flags] десериализатор не узнает, что значение может быть комбинацией флагов. Я усвоил это на собственном горьком опыте, потратив около двух дней на размышления, почему мой WCF не работает.
@leppie следует использовать атрибут flags, чтобы указать, что вы можете использовать побитовое ИЛИ. Использование его в перечислениях, которые не отмечены им, вероятно, не будет иметь степени 2, что приведет к беспорядку.
Если бы я провел сканирование покрытия кода, я думаю, что эти два были бы лучшими:
[Serializable]
[WebMethod]
[WebMethod] используется для украшения метода, который предоставляется в веб-службе. [Serializable] помечает ваши объекты так, чтобы их можно было сериализовать для таких целей, как передача их между доменами приложений.
В духе Хофштадта атрибут [Attribute] очень полезен, поскольку с его помощью вы создаете свои собственные атрибуты. Я использовал атрибуты вместо интерфейсов для реализации систем плагинов, добавления описаний в Enums, имитации множественной диспетчеризации и других трюков.
Звучит круто! Не могли бы вы показать несколько примеров системы плагинов и описаний перечислений? Я заинтересован в том, чтобы реализовать обе эти вещи!
На мой взгляд, System.Obsolete - один из самых полезных атрибутов в фреймворке. Возможность выдавать предупреждение о коде, который больше не следует использовать, очень полезна. Мне нравится иметь способ сказать разработчикам, что что-то больше не следует использовать, а также иметь способ объяснить, почему и указать на лучший / новый способ что-то делать.
Conditional attribute также очень удобен для отладки. Он позволяет добавлять в код методы для отладки, которые не будут компилироваться при сборке решения для выпуска.
Кроме того, есть много атрибутов, специфичных для веб-элементов управления, которые я считаю полезными, но они более специфичны и не используются вне рамок разработки серверных элементов управления из того, что я нашел.
Мне нравится флаг устаревшего, но он просто вызывает предупреждение. Большинство людей, с которыми я столкнулся, игнорируют предупреждения в VS
Да, я тоже это заметил. Я работал над приложениями, где есть сотни предупреждений. Большинство из них нужно было исправить, но не по какой-то причине. Я никогда этого не понимал ...
Вы можете передать «true» в качестве одного из параметров System.Obsolete, что приведет к тому, что предупреждение станет ошибкой, что приведет к нарушению сборки. Очевидно, это следует сделать после того, как вы удалите все предупреждения. :)
После того, как вы очистите все предупреждения, не лучше ли просто удалить метод?
@Pedro: Иногда это невозможно по причинам обратной совместимости. Если он частный и неиспользуемый, да, удалите его.
В отношении Obsolete следует отметить одну вещь: вы всегда можете обойти ошибку компиляции, обратившись к методу через отражение. Даже с ошибкой компиляции лучше также добавить метод, если вам нужно его оставить.
@plinth Создание исключения было бы плохой идеей по многим причинам. №1 заключается в том, что основная причина использования Obsolete () заключается в том, чтобы вы могли продолжать работу скомпилированного кода во время переходной фазы. Если вы не разрешаете никому вызывать метод, почему бы просто не удалить его?
@Dan - если вы отметите Obsolete с ошибкой с ошибкой при компиляции, то он не должен вызываться Когда-либо. Если он вызывается во время выполнения, значит кто-то нарушил Устаревший ...
@plinth Это предотвращает использование метода кодом новый. Старый код останется двоично-совместимым, если метод помечен как устаревший, но он перестанет работать, если вы создадите исключение. Если кто-то использует отражение, чтобы обойти флаг "Obsolte", то у вас проблемы похуже ...
Недавно я написал статью об использовании условных атрибутов для отладки. На самом деле мне нравится использовать их больше, чем точки останова в определенных случаях. Вот несколько примеров ... codefromjames.com/wordpress/?p=131
Если вы выпускаете свои библиотеки DLL как API с поддержкой версий, вы можете сохранить метод устаревших ошибок, чтобы люди могли получить информацию о том, почему он больше не работает, а не о том, что метод просто не существует. [Obsolete( "Use X instead", true )] указывает причину, по которой код не компилируется, и предлагает альтернативу.
Как бы то ни было, вот список всех атрибутов .NET. Их несколько сотен.
Я не знаю ни о ком другом, но мне нужно серьезно заняться RTFM!
опубликованный список для .net 1.1 вот список для 3.5 msdn.microsoft.com/en-us/library/system.attribute.aspx (вам нужно немного прокрутить вниз)
Обновил ссылку в вопросе. Теперь это полный список для 3.5
Собственно то ссылки на последнюю, а не на 3.5 конкретно.
Вот если бы список был не просто списком ссылок, а именем и описанием. Ну что ж. @BrianOrtiz прав. Список находится в версии 4.5.
Вы просто меняете целевую платформу вверху, где написано «Другие версии».
[DebuggerDisplay] может быть действительно полезен для быстрого просмотра настроенного вывода типа при наведении указателя мыши на экземпляр типа во время отладки. пример:
[DebuggerDisplay("FirstName = {FirstName}, LastName = {LastName}")]
class Customer
{
public string FirstName;
public string LastName;
}
Вот так это должно выглядеть в отладчике:

Также стоит упомянуть, что атрибут [WebMethod] с набором свойств CacheDuration позволяет избежать ненужного выполнения метода веб-службы.
Вау, это действительно хорошо знать. Обычно я делал то же самое, переопределяя ToString, но это лучше.
Будьте осторожны, он откусывает гораздо больший кусок вашего процессора, чем ToString.
Вы также можете использовать это для отображения результатов методов. Это может вызвать затруднения при отладке, если метод (или свойство get) имеет побочные эффекты.
@ NikolaRadosavljević будет ли он потреблять мощность процессора только во время отладки
@Nickolay Kondratyev: Я не знаю всех тонкостей, но вы можете взглянуть на следующие передовые практики веб-сервисов, которые помогут вам сделать некоторые выводы: blogs.msdn.com/b/jaredpar/archive/2011/03/18/…
@Nikola: там говорится только о производительности отладки.
@Brian Почему так лучше, могу я спросить? Он достигает только одной цели, в то время как ToString достигает обеих. Я не уверен, что понимаю назначение этого атрибута.
@Ken: см. Зачем переопределять ToString ()?
Каждый раз, когда у вас есть curly, оценивается внутренняя часть, на что тратится центральный процессор, 2x curly равняется 2x вызовам eval, поэтому чрезмерное количество вызовов может стоить много ресурсов процессора (fx. Показывает длинный список элементов). обходной путь к этому - вызов {DebuggerDisplay()}, который является только одним дорогостоящим вызовом, и вы можете заставить этот метод возвращать все имена свойств, которые вам нужны. Также, если метод является частным, он технически нигде не используется и будет удален во время сборки Release. но отладчик все еще может использовать его во время отладки.
Я бы посоветовал [TestFixture] и [Test] - из библиотеки nUnit.
Модульные тесты в вашем коде обеспечивают безопасность при рефакторинге и кодифицированной документации.
Мне нравится [DebuggerStepThrough] из System.Diagnostics.
Это очень удобно, чтобы избежать использования однострочных методов или свойств, которые ничего не делают (если вы вынуждены работать в раннем .Net без автоматических свойств). Поместите атрибут в короткий метод или в средство получения или установки свойства, и вы пролетите мимо, даже нажав «шаг в» в отладчике.
Так много раз я хотел бы знать об этой собственности
Жаль, что он сломан из-за закрытия - см. gregbeech.com/blogs/tech/archive/2008/10/17/… для получения дополнительной информации.
Также полезно для любого кода WM_Paint, который, как вы знаете, работает :)
@GregBeech Этот URL возвращает ошибку .NET. Классно! :)
@smdrager - Должно быть, это временная проблема, похоже, сегодня у меня работает.
[DebuggerHidden] - еще один хороший. Это заставляет выброшенные ошибки прерываться в вызывающем методе (для таких вещей, как обработчики БД)
Как разработчик среднего уровня мне нравится
System.ComponentModel.EditorBrowsableAttribute Позволяет мне скрывать свойства, чтобы разработчик пользовательского интерфейса не был перегружен свойствами, которые им не нужно видеть.
System.ComponentModel.BindableAttribute Некоторые вещи не нужно связывать с данными. Опять же, сокращает объем работы, необходимой разработчикам пользовательского интерфейса.
Мне также нравится DefaultValue, о котором упоминал Лоуренс Джонстон.
System.ComponentModel.BrowsableAttribute и Flags используются регулярно.
я использую
System.STAThreadAttribute
System.ThreadStaticAttribute
при необходимости.
Кстати. Они не менее ценны для всех разработчиков .Net framework.
Чаще всего я использую атрибуты, связанные с сериализацией XML.
XmlRoot
XmlElement
XmlAttribute
так далее...
Чрезвычайно полезно при выполнении любого быстрого и грязного синтаксического анализа или сериализации XML.
Компилятор поддерживает только несколько атрибутов, но одно очень интересное использование атрибутов находится в AOP: PostSharp использует ваши индивидуальные атрибуты для внедрения IL в методы, позволяя использовать всевозможные возможности ... log / trace являются тривиальными примерами, но некоторые другие хорошие примеры такие вещи, как автоматическая реализация INotifyPropertyChanged (здесь).
Некоторые из них встречаются и напрямую влиять на компилятор или среду выполнения:
[Conditional("FOO")] - вызовы этого метода (включая оценку аргументов) происходят только в том случае, если во время сборки определен символ "FOO".[MethodImpl(...)] - используется для обозначения некоторых вещей, таких как синхронизация, встраивание[PrincipalPermission(...)] - используется для автоматической вставки проверок безопасности в код[TypeForwardedTo(...)] - используется для перемещения типов между сборками без перестройки звонящихДля вещей, которые проверяются вручную через отражение - я большой поклонник атрибутов System.ComponentModel; такие вещи, как [TypeDescriptionProvider(...)], [TypeConverter(...)] и [Editor(...)], которые могут полностью изменить поведение типов в сценариях привязки данных (например, динамические свойства и т. д.).
[TypeConverter(typeof(ExpandableObjectConverter))]
Сообщает дизайнеру расширить свойства, которые являются классами (вашего контроля)
[Obfuscation]
Дает указание средствам обфускации выполнять указанные действия для сборки, типа или элемента. (хотя обычно вы используете уровень сборки [assembly:ObfuscateAssemblyAttribute(true)]
Я догадался, но ошибся. Атрибут обфускации - это всего лишь подсказка для сторонних обфсукаторов. Это не заставляет компилятор что-либо скрывать по умолчанию.
@DanNeely бесплатно для пользователей Visual Studio Pro / Ultimate!
Если вы имеете в виду DotFuscator Community Edition, уровень защиты настолько низок, что в лучшем случае он почти ни для чего не учитывается.
@ricovox Я добавил резюме
[XmlIgnore]
поскольку это позволяет игнорировать (в любой сериализации xml) «родительские» объекты, которые в противном случае могли бы вызвать исключения при сохранении.
// on configuration sections
[ConfigurationProperty]
// in asp.net
[NotifyParentProperty(true)]
какова цель NotifyParentProperty?
В последнее время пользуюсь [DataObjectMethod]. Он описывает метод, поэтому вы можете использовать свой класс с ObjectDataSource (или другими элементами управления).
[DataObjectMethod(DataObjectMethodType.Select)]
[DataObjectMethod(DataObjectMethodType.Delete)]
[DataObjectMethod(DataObjectMethodType.Update)]
[DataObjectMethod(DataObjectMethodType.Insert)]
В нашем текущем проекте мы используем
[ComVisible(false)]
Он контролирует доступность отдельного управляемого типа или члена или всех типов в сборке для COM.
Мне нравится использовать атрибут [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 позволяет мне ограничивать вызов только рассматриваемым потоком, избегая запутанной проблемы доступа к данным между потоками.
а как тогда получить доступ? Не понимаю смысла вашего образца использования здесь. Вы можете объяснить?
@Beachwalker Current должен быть статическим, отредактировал его сейчас. Теперь вы можете получить доступ к MyContextInformation.Current, чтобы получить активный контекст в стеке. Это то, что в некоторых случаях является очень хорошей концепцией, наш (моей компании) движок использует ее для множества целей.
DesignerSerializationVisibilityAttribute очень полезен. Когда вы помещаете свойство среды выполнения в элемент управления или компонент и не хотите, чтобы дизайнер сериализовал его, вы используете его следующим образом:
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Foo Bar {
get { return baz; }
set { baz = value; }
}
очень полезно для компонентов WinForms. использовать вместе с [Browsable (false)]
Хороший момент - [Browsable(false)] требуется, чтобы скрыть его от пользователя разработчика, тогда как [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] требуется, чтобы он не был сериализован.
Я всегда использую атрибуты 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-комментарий не найден. Это позволило бы избежать повторения одного и того же предложения дважды.
Не могу поверить, что никто не указал Description, пока вы не .. Это наиболее полезно для меня при использовании с перечислениями ..
[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() { }
}
Здесь - пост про интересный атрибут Внутреннее устройство. В основном то, что он делает, он имитирует функциональность доступа друзей C++. Это очень удобно для модульного тестирования.
Разве вы не имеете в виду удобство для взлома модульного теста на то, что нельзя / не нужно тестировать?
@the_drow: Вы говорите о «частных аксессуарах»: msdn.microsoft.com/en-us/library/ms184807%28v=vs.80%29.aspx
@habakuk: Не совсем. Есть случаи, когда внутренние классы должны быть представлены для модульного тестирования, обычно из-за плохого дизайна.
@the_drow: Я бы не сказал, что InternalsVisibleTo вреден для модульного тестирования; вы можете создавать и тестировать меньшие «юниты», которые не видны за пределами вашего проекта (это помогает вам иметь чистый и небольшой api). Но если вам нужны «частные аксессоры» для модульного тестирования, то, вероятно, что-то не так.
@habakuk: Если нужно протестировать, он должен быть общедоступным.
@the_drow Я не согласен с вашим утверждением, что internal не является общедоступным. Он общедоступен в тестируемой сборке и должен проходить модульное тестирование, чтобы другие классы в сборке могли предположить, что это функция исправления. Если вы его не тестируете, вам придется протестировать его функции во всех потребляющих классах.
Я бы проголосовал за Conditional
[Conditional("DEBUG")]
public void DebugOnlyFunction()
{
// your code here
}
Вы можете использовать это, чтобы добавить функцию с расширенными функциями отладки; как и Debug.Write, он вызывается только в отладочных сборках и поэтому позволяет вам инкапсулировать сложную логику отладки вне основного потока вашей программы.
Разве это не то же самое, что делать #if DEBUG?
В некотором смысле, #if DEBUG означает, что вызывающий объект также не должен вызывать его, в то время как Conditioinal оставляет вызов, но делает его NOP, который удаляется при JIT.
Кроме того, вы обычно используете #if DEBUG вокруг звонки и [Conditional] вокруг методы. Поэтому, если вы вызываете метод отладки 100 раз, его отключение зависит от одного изменения кода, а не 100 раз.
Комментарий Рангорика несколько неверен (по крайней мере, для C#): метод включен без изменений; сам сайт вызова опускается. Это имеет несколько последствий: параметры не оцениваются, а условный метод содержится в выводе компилятора без изменений. Вы можете убедиться в этом с помощью рефлексии. msdn.microsoft.com/en-us/library/aa664622.aspxblogs.msdn.com/b/jmstall/archive/2007/10/15/…
Он плохо назван, плохо поддерживается во фреймворке и не требует параметра, но этот атрибут является полезным маркером для неизменяемых классов:
[ImmutableObject(true)]
Согласно документации, используется только во время разработки (к сожалению).
Учитывая, что это только время разработки, возможно, было бы лучше создать свой собственный класс ImmutableObjectAttribute - по крайней мере, вы могли бы исключить этот параметр.
[DeploymentItem("myFile1.txt")]Документ MSDN по DeploymentItem
Это действительно полезно, если вы тестируете файл или используете файл в качестве входных данных для вашего теста.
Я генерирую класс сущности данных через 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;
}
}
}
Внезапно, вот краткий список, примерно отсортированный по частоте использования, предопределенных атрибутов, которые я действительно использую в большом проекте (~ 500k LoC):
Флаги, Сериализуемый, WebMethod, COMVisible, TypeConverter, Conditional, ThreadStatic, Obsolete, InternalsVisibleTo, DebuggerStepThrough.
+1 для ThreadStatic, удивлен, что никто не упомянул об этом до сих пор, а также для статистического подхода
[EditorBrowsable(EditorBrowsableState.Never)] позволяет скрыть свойства и методы от IntelliSense, если проект отсутствует в вашем решении. Очень полезно для сокрытия недопустимых потоков для свободных интерфейсов. Как часто вы хотите использовать GetHashCode () или Equals ()?
Для MVC [ActionName("Name")] позволяет вам иметь действия Get и Post с одной и той же сигнатурой метода или использовать тире в имени действия, что в противном случае было бы невозможно без создания для него маршрута.
Я всегда использую атрибуты,
[Serializable], [WebMethod], [DefaultValue], [Description("description here")].
но кроме этого в C# есть Глобальные атрибуты.
[assembly: System.CLSCompliant(true)]
[assembly: AssemblyCulture("")]
[assembly: AssemblyDescription("")]
Я считаю важным упомянуть здесь, что следующие атрибуты также очень важны:
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;
}
Используется ли STAThread для предотвращения случайного запуска вашего приложения другим экземпляром при запуске?
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)) и в обернутом методе возникает ошибка, стек вызовов не показывает метод, который вызывает метод, который вызывает ошибку.
Что за вопрос? , вся страница переполнена красивыми ответами с замечательными объяснениями. Пока я читал это, я получил опыт, например, опросил многих экспертов по поводу их взглядов. +100 за вопрос.