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

784

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

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

Wusher
источник
27
Что за вопрос? , вся страница переполнена красивыми ответами с чудесными объяснениями. Пока я читаю это, у меня появился опыт, как опросить многих экспертов о своем мнении. +100 за вопрос.
Мутху Ганапати Натан
Я согласен, такие вопросы являются одними из самых ценных - делает ТАК менее полезным, потому что он закрывается.
Дэвид Тилен

Ответы:

669

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

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

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

альтернативный текст

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

Vivek
источник
62
Вау, это действительно приятно знать. Я обычно добивался того же, переопределяя ToString, но это лучше.
Брайан
17
Будьте осторожны с этим, он отнимает гораздо больший кусок вашего процессора, чем ToString.
Никола Радосавлевич
1
Вы также можете использовать это для отображения результатов методов. Это может создать довольно запутанный опыт отладки, если у метода (или свойства-get) есть побочные эффекты.
Ойвинд Скаар
4
@ NikolaRadosavljević будет только потреблять мощность процессора во время отладки
Николай Кондратьев
2
@ Николай Кондратьев: Я не знаю всех входов и выходов, но вы можете взглянуть на следующие рекомендации по веб-сервисам, которые помогут
Никола Радосавлевич
273

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

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

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

Dan Herbert
источник
50
Вы можете передать «true» в качестве одного из параметров в System.Obsolete, что приведет к тому, что предупреждение станет ошибкой, что приведет к нарушению сборки. Очевидно, это следует сделать после того, как вы очистите все предупреждения. :)
Адриан Кларк
14
Как только вы уберете все предупреждения, не лучше ли просто удалить метод?
Педро
10
@Pedro: Иногда вы не можете по причинам обратной совместимости. Если это приватно и не используется, да, удалите его.
Фантиус
3
@plinth Создание исключения было бы плохой идеей по многим причинам, поскольку первая причина заключается в том, что основная причина использования Obsolete () заключается в том, чтобы вы могли поддерживать работу скомпилированного кода, находясь в фазе перехода. Если вы не позволяете никому вызывать метод, почему бы просто не удалить его?
Дэн Герберт
17
@plinth Это чтобы новый код не использовал метод. Старый код останется двоично-совместимым, если метод помечен как устаревший, но он перестанет работать, если вы сгенерируете исключение. Если кто-то использует отражение, чтобы обойти флаг «Obsolte», то у вас проблемы хуже ...
Дэн Герберт,
204

[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"

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

Shog9
источник
Так что именно делает атрибут Flags?
Андрей Ринея
13
Надеюсь, что вы, ребята, понимаете, что атрибут Flags действительно поражает всех. Он не нужен / не используется вообще, кроме TypeConverter.
Леппи
3
@leppie: ToString () также. Но ... вау. По какой-то причине я ожидал, что поведение перечислений без атрибута будет таким же, как в C ++: или значения будут производить целое число (нельзя передать как есть в метод, ожидающий перечисление param). Теперь я вижу, что это не так. Слабая ... окей, .NET перечисляет отстой
Shog9
2
[Flags] действительно только помогает функциям отладчика и .ToString () знать, что значение потенциально является комбинацией нескольких объявлений в перечислении. Я не уверен, что это может помочь Intellisense помочь вам использовать перечисление более эффективно.
Кензи
31
[Flags]действительно имеет большее применение, чем просто синтаксический сахар. При использовании веб-сервисов сериализация / десериализация не будет работать, если SandwichStuff.Cheese | SandwichStuff.Ham | SandwichStuff.Jamпередано значение наподобие . Без [Flags]атрибута десериализатор не будет знать, что значение может быть комбинацией флагов. Узнал об этом нелегко, потратив около двух дней на размышления о том, почему мой WCF не работает.
Анчит
177

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

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

Blair Conrad
источник
5
Столько раз я хотел бы знать об этой собственности
wusher
1
Просто позор, что он сломан замыканиями - см. Gregbeech.com/blogs/tech/archive/2008/10/17/… для получения дополнительной информации.
Грег Бич
3
Также полезно для любого кода WM_Paint, который, как вы знаете, работает :)
Pondidum
@GregBeech Этот URL возвращает ошибку .NET. Классный! :)
smdrager
@smdrager - Должно быть, это временная проблема, кажется, работает для меня сегодня.
Грег Бич
135

Для чего это стоит, вот список всех атрибутов .NET . Есть несколько сотен.

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

wprl
источник
33
опубликованный список для .net 1.1 вот список для 3.5 msdn.microsoft.com/en-us/library/system.attribute.aspx (нужно немного прокрутить вниз)
kay.one
2
Обновил ссылку в вопросе. Теперь это полный список для 3.5
Р. Мартиньо Фернандес
8
На самом деле это ссылки на последние, а не 3,5 конкретно.
Брайан Ортис
1
Теперь, если бы только список был не просто списком ссылок, а именем и описанием. Ну что ж. @BrianOrtiz прав. Список находится в версии 4.5.
Световой
Вы просто меняете фреймворк, на который вы нацелены, вверху, где написано «Другие версии».
Новатерата
129

Мой голос будет за Conditional

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

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

Стив Купер
источник
5
разве это не то же самое, что делать #if DEBUG?
Нил Н
10
В некотором смысле, #if DEBUG означает, что вызывающий абонент также не должен вызывать его, в то время как Conditioinal оставляет вызов, но делает его NOP, который удаляется в JIT.
Rangoric
23
Кроме того, вы обычно используете #if DEBUG для вызовов и [Conditional] для методов . Поэтому, если вы вызываете метод отладки 100 раз, его отключение - это одно изменение кода, а не 100.
Стив Купер
13
Комментарий Рангорича немного неверен (по крайней мере, для C #): метод включен без изменений; сам сайт вызова опущен. Это имеет несколько последствий: параметры не оцениваются, а условный метод содержится без изменений в выходных данных компилятора. Вы можете проверить это с помощью отражения. msdn.microsoft.com/en-us/library/aa664622.aspx blogs.msdn.com/b/jmstall/archive/2007/10/15/…
Марк Соул
97

Я всегда использую 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. Это позволит избежать повторения одного и того же предложения дважды.

Энтони Брайен
источник
3
Не могу поверить, что никто не указал, Descriptionпока вы .. Это наиболее полезно для меня, когда используется с перечислениями ..
nawfal
68

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

Gilligan
источник
На самом деле он ссылается на psuedoattribute, так как C # испускает флаг метаданных для [Serializable], а не экземпляр пользовательского атрибута;)
TraumaPony
1
Хотя очень полезный [Serializable] далеко не идеален. Для достижения желаемого результата требуется слишком много усилий и проб и ошибок.
Shoosh
Я поддержу это!
Джон Бубриски
System.NonSerializedAttribute полезен, если вы хотите больше контроля над автоматической сериализацией.
CSharper
В качестве дополнительного примечания я хотел бы добавить, что производительность встроенной сериализации .Net довольно низкая, примерно на 2 или 3 порядка медленнее, чем код, созданный вручную.
Redcalx
57

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

C. Lawrence Wenham
источник
13
Звучит круто! Не могли бы вы показать несколько примеров системы плагинов и описания enum? Это обе вещи, которые я заинтересован в реализации себя!
Джон Бубриски
46

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

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

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

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

Adrian Wible
источник
26
[XmlIgnore]

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

jimi
источник
25

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

[ImmutableObject(true)]
Нил Уитакер
источник
6
Согласно документации, используется только во время разработки (к сожалению).
Ганс Кеинг
1
Учитывая, что это только время разработки, возможно, было бы лучше создать свой собственный ImmutableObjectAttributeкласс - по крайней мере, вы могли бы исключить параметр.
Рой Тинкер
25

Мне нравится использовать [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 позволяет мне охватить вызов только рассматриваемым потоком, избегая беспорядочной проблемы доступа к данным через потоки.

Ajaxx
источник
а как получить доступ то? Не понимаю смысл вашего примера использования здесь. Вы можете объяснить?
Beachwalker
@Beachwalker Ток должен быть статичным, отредактировал его сейчас. Теперь вы можете получить доступMyContextInformation.Current к активному контексту в стеке. В некоторых случаях это очень хорошая концепция, наша (моя компания) система использует ее для многих целей.
Феликс К.
23

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))и в упакованном методе возникает ошибка, стек вызовов не показывает метод, который вызывает метод, который выдает ошибку.

Феликс К.
источник
21

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

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Foo Bar {
    get { return baz; }
    set { baz = value; }
}
конфигуратор
источник
4
очень полезно для компонентов WinForms. использовать совместно с [Browsable (false)]
Mark Heath
3
Хороший вопрос - [Browsable(false)]требуется скрыть его от пользователя дизайнера, где [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]это необходимо, чтобы его не сериализовали.
конфигуратор
17

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

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

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

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

Марк Гравелл
источник
15

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

 [Serializable]
 [WebMethod]
FlySwat
источник
15
[WebMethod] используется для оформления метода, предоставляемого в веб-сервисе. [Сериализуемый] помечает ваши объекты так, чтобы их можно было сериализовать для таких целей, как их передача через домены приложения.
Кев
15

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

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

Больше информации

wusher
источник
12

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

[ComVisible(false)]

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

Больше информации

Ахмед
источник
12
[TypeConverter(typeof(ExpandableObjectConverter))]

Говорит конструктору расширить свойства, которые являются классами (вашего контроля)

[Obfuscation]

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

Chris S
источник
1
Я угадал, но был неправ. Атрибут Obfuscation - это только подсказка для сторонних obfsucators. Это не заставляет компилятор ничего запутывать по умолчанию.
Дэн возится с Firelight
@DanNeely бесплатно для пользователей Visual Studio Pro / Ultimate!
Крис С
4
Если вы имеете в виду DotFuscator Community Edition, то уровень защиты настолько низок, что в лучшем случае он ничего не значит.
Дэн возится с Firelight
@ricovox Я добавил резюме
Крис С
9

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

XmlRoot

XmlElement

XmlAttribute

так далее...

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

Brannon
источник
8

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

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

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

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

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

Я использую, System.STAThreadAttribute System.ThreadStaticAttribute когда это необходимо.

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

ElGringoGrande
источник
8

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

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

smdrager
источник
8

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

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 для предотвращения случайного вращения вашего приложения при запуске другого экземпляра?
Световой
7

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

Флаги, Сериализуемый, WebMethod, COMVisible, TypeConverter, Условный, ThreadStatic, Устаревший, InternalsVisibleTo, DebuggerStepThrough.

Eldritch Conundrum
источник
2
+1 для ThreadStatic, удивило, что никто не упомянул это до сих пор, а также для статистического подхода
staafl
6

Я генерирую класс сущности данных через 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;
    }
}
}
Ming Yeh
источник
6

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

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

Kevin Driedger
источник
5

[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() { }
}
CSharper
источник