Найкорисніші атрибути [закрито]


784

Я знаю, що атрибути надзвичайно корисні. Є деякі заздалегідь визначені такі, [Browsable(false)]які дозволяють приховати властивості на вкладці властивостей. Ось хороше запитання, що пояснює атрибути: Що таке атрибути в .NET?

Які заздалегідь визначені атрибути (та їх область імен) ви фактично використовуєте у своїх проектах?


27
Яке питання? , вся сторінка переповнена красивими відповідями з чудовими поясненнями. Поки я читаю це, я отримав досвід, як інтерв'ю багатьох експертів про їхній погляд. +100 для питання.
Муту Ганапатій Натан

Я погоджуюсь, такі питання є одними з найцінніших - ТА робить менш корисним, що закривається.
Девід Тілен

Відповіді:


669

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

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

Ось як це має виглядати в налагоджувачі:

alt текст

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


62
О, це справді добре знати. Зазвичай я робив те саме, що переосмислив ToString, але це краще.
Брайан

17
Будьте обережні з цим, це відкушує набагато більший шматок вашого процесора, ніж ToString.
Микола Радосавлевич

1
Ви також можете використовувати це для відображення результатів методів. Це може призвести до досить заплутаного досвіду налагодження, якщо метод (або отримання властивості) має побічні ефекти.
Øyvind Skaar

4
@ NikolaRadosavljević міг би зайняти потужність процесора лише під час налагодження
Микола Кондратєв

2
@Nickolay Kondratyev: Я не знаю всіх надходжень і недоліків, але ви можете ознайомитись з дотриманням кращих практик роботи веб-сервісу, які можуть зробити вас висновками: blogs.msdn.com/b/jaredpar/archive/2011/03/ 18 /…
Нікола Радосавлевич

273

System.ObsoleteНа мою думку, це один із найкорисніших атрибутів у рамках. Можливість викликати попередження про код, який більше не слід використовувати, дуже корисна. Я люблю мати спосіб сказати розробникам, що щось більше не слід використовувати, а також мати спосіб пояснити, чому і вказувати на кращий / новий спосіб щось робити.

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

Тоді є багато атрибутів, характерних для веб-керування, які я вважаю корисними, але вони є більш конкретними і не мають ніякого використання поза розробкою серверних елементів управління, ніж те, що я знайшов.


50
Ви можете передати "true" як один із параметрів System.Obsolete, який спричиняє попередження про помилку, тому порушує збірку. Очевидно, що це слід зробити, як тільки ви очистили всі попередження. :)
Адріан Кларк

14
Після того, як ви очистите всі попередження, чи не буде краще просто видалити метод?
Педро

10
@Pedro: Іноді не можна з міркувань зворотної сумісності. Якщо він приватний і не використовується, так, видаліть його.
Fantius

3
@plinth Метання винятків було б поганою ідеєю з багатьох причин, тому що №1 полягає в тому, що головна причина використання застарілого () - це ви можете тримати компільований код під час перехідної фази. Якщо ви не дозволяєте нікому викликати метод, чому б просто не видалити його?
Ден Герберт

17
@plinth Це запобігання новому коду від використання методу. Старий код залишатиметься бінарним сумісним, якщо метод позначений застарілим, але він припинить роботу, якщо викинете виняток. Якщо хтось використовує роздуми, щоб обійти прапор "Обсольте", то у вас є ще гірші проблеми ...
Ден Герберт

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"

Леппі вказує на те, що я не усвідомлював, і що досить пригнічує моє захоплення цим атрибутом: він не вказує компілятору допускати комбінації бітів як допустимих значень для змінних змінних, компілятор дозволяє це робити для перерахунку незалежно. Мій фон C ++, що відображається через ... зітхання


То що саме робить атрибут Flags?
Андрій Ронеа

13
Я сподіваюся, ви, хлопці, усвідомлюєте, що атрибут "Прапори" все хизує. Він взагалі не потрібен / використовується, за винятком TypeConverter.
леппі

3
@leppie: Також ToString (). Але ... вау. Чомусь я очікував, що поведінка перерахувань без атрибуту буде такою самою, як C ++: або значення значень виробляють ціле число (не може бути передано як - це метод, що очікує парамуму перерахунку). Я зараз бачу, що це не так. Слабкий ... добре,. NET перераховує смоктати.
Shog9

2
[Прапори] насправді лише допомагає налагоджувачу та .ToString () функціям знати, що значення потенційно є комбінацією декількох декларацій в переліку. Я не впевнений, це може змусити Intellisense допомогти вам і ефективніше використовувати enum.
Кензі

31
[Flags]має більше користі, ніж просто синтаксичний цукор. Під час використання веб-сервісів серіалізація / десеріалізація не працюватиме, якщо SandwichStuff.Cheese | SandwichStuff.Ham | SandwichStuff.Jamпередане значення типу . Без [Flags]атрибута десеріалізатор не дізнається, що значення може бути комбінацією прапорів. Навчився цьому важким шляхом, витративши близько двох днів на роздуми, чому мій WCF не працює.
Анхіт

177

Мені подобається [DebuggerStepThrough]від System.Diagnostics .

Це дуже зручно, щоб уникнути того, щоб уникнути тих однолінійних методів чи властивостей, які не роблять нічого (якщо ви змушені працювати на початку. Net без автоматичних властивостей). Помістіть атрибут на короткий метод або на getter або setter властивості, і ви будете літати прямо, навіть натискаючи "крок у" у налагоджувачі.


5
Стільки разів я хотів би, щоб я знав про цю власність
вранці

1
Прикро, що це порушено із закриттями - див. Gregbeech.com/blogs/tech/archive/2008/10/17/… для отримання додаткової інформації.
Грег Бук

3
Також корисно для будь-якого коду WM_Paint, який ви знаєте, працює :)
Pondidum,

@GregBeech Ця URL-адреса повертає помилку .NET. Класно! :)
smdrager

@smdrager - Мабуть, тимчасова проблема, здається, працює для мене сьогодні.
Грег Бук

135

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

Я не знаю ні про кого іншого, але я маю зробити кілька серйозних RTFM!


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?
Ніл N

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 або з віддаленого сервера. Більше про це тут.


Насправді це посилається на psuedoattribute, оскільки C # випускає прапор метаданих для [Serializable], а не спеціальний екземпляр атрибута;)
TraumaPony,

1
Хоча дуже корисна [Serializable] - далеко не ідеальна. Для отримання потрібного результату потрібно занадто багато хитрощі, спроб та помилок.
shoosh

Я відправлю цей шош!
Джон Бубріскі

System.NonSerializedAttribute корисний, якщо ви хочете більше контролювати автоматичну серіалізацію.
CSharper

В якості додаткового зауваження я хочу додати, що продуктивність вбудованої .Net серіалізації досить низька, як на 2 або 3 порядки повільніше, ніж в ручному коді.
redcalx

57

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


13
Звучить круто! Ви б не хотіли показати кілька прикладів системи плагінів та описів enum? Це обидва речі, які мені цікаво реалізувати!
Джон Бубріскі

46

Ось публікація про цікавий атрибут InternalsVisibleTo . В основному те, що це робить, імітує функцію доступу друзів C ++. Це дуже зручно для тестування одиниць.


7
Ви не маєте на увазі зручності для злому одиничного тесту на те, що не можна було / не слід перевіряти?
the_drow

@the_drow: Ви говорите про "приватні доступні
habakuk

@habakuk: Не дуже. Бувають випадки, коли внутрішні класи повинні піддаватися тестуванню одиниць, як правило, через поганий дизайн.
the_drow

2
@the_drow: Я б не сказав, що InternalsVisibleTo є злом для тестування одиниць; ви можете створити і протестувати менші "одиниці", які не видно поза вашим проектом (це допомагає вам мати чисту і маленьку api). Але якщо для тестування чогось вам потрібні "приватні підключення", можливо, щось не так.
хабакук

10
@the_drow Я не згоден з вашим твердженням, яке internalне є загальнодоступним. Загальнодоступність у складі тестується і має бути перевірена одиницею, щоб інші класи в межах збірки могли припускати, що це корекційна функціональність. Якщо ви не підключите тест, вам доведеться перевірити його функції у всіх споживчих класах.
tvanfosson


28

Я б запропонував [TestFixture]і [Test]- з бібліотеки nUnit .

Тестові одиниці у вашому коді забезпечують безпеку рефакторингу та кодифікованої документації.


26
[XmlIgnore]

оскільки це дозволяє ігнорувати (у будь-якій xml серіалізації) 'батьківські' об’єкти, які в іншому випадку можуть спричинити винятки при збереженні.


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 дозволяє мені охоплювати виклик лише до поточного потоку, уникаючи безладної проблеми доступу до даних через потоки.


і як тоді отримати доступ? Тут не розумієте суть вашого зразка використання. Ви можете пояснити?
Beachwalker

@Beachwalker Current має бути статичним, редагувати його зараз. Тепер ви можете отримати доступ, 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. використовувати спільно з [Browvable (false)]
Марк Хіт

3
Хороший момент - [Browsable(false)]потрібно приховати його від користувача дизайнера, де [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]це потрібно, щоб воно не отримало серіалізації.
конфігуратор

17

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

Деякі з них, які безпосередньо впливають на компілятор або час виконання :

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

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


15

Якби я пройшов сканування кодового покриття, я думаю, що ці два будуть найкращими:

 [Serializable]
 [WebMethod]

15
[WebMethod] використовується для прикраси методу, який відкривається у веб-сервісі. [Serializable] позначає ваші об’єкти таким чином, що вони можуть бути серіалізовані для таких цілей, як передача їх по домену додатків.
Кев

15

Я використовую [DataObjectMethod]останнім часом. Він описує метод, щоб ви могли використовувати свій клас із ObjectDataSource (або іншими елементами управління).

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

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


12

У нашому поточному проекті ми використовуємо

[ComVisible(false)]

Він контролює доступ до СОМ окремого керованого типу або члена, або всіх типів у складі.

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


12
[TypeConverter(typeof(ExpandableObjectConverter))]

Розповідає дизайнеру про розширення властивостей, які є класами (вашого контролю)

[Obfuscation]

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


1
Я гадав, але помилявся. Атрибут Obfuscation - лише підказка для сторонніх обскураторів. Це не змушує компілятора замовчувати що-небудь за замовчуванням.
Dan Dan Fiddling Firelight

@DanNeely безкоштовно для користувачів Visual Studio Pro / Ultimate!
Chris S

4
Якщо ви маєте на увазі DotFuscator Community Edition, рівень захисту надається настільки низький, що в кращому випадку він ледве не рахується ні за що.
Dan Dan Fiddling Firelight

@ricovox Я додав резюме
Chris S

9

Атрибути, які я найбільше використовую, стосуються серіалізації XML.

XmlRoot

XmlElement

XmlAttribute

тощо ...

Надзвичайно корисно робити будь-який швидкий і брудний аналіз XML або серіалізацію.


8

Мені подобається бути розробником середнього рівня

System.ComponentModel.EditorBrowsableAttribute Дозволяє приховати властивості, щоб розробник інтерфейсу не був переповнений властивостями, які їм не потрібно бачити.

System.ComponentModel.BindableAttributeДеякі речі не потрібно обв'язувати даними. Знову ж таки, зменшується робота розробників інтерфейсу користувача.

Мені також подобається той DefaultValueзгаданий Лоуренс Джонстон.

System.ComponentModel.BrowsableAttributeі Flagsвикористовуються регулярно.

Я використовую, System.STAThreadAttribute System.ThreadStaticAttribute коли потрібно.

Між іншим. Я це так само цінний для всіх розробників фреймворків .Net.


8

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

Для MVC [ActionName("Name")]дозволяє мати дію Get Get і Post з тим самим підписом методу або використовувати тире в імені дії, що в іншому випадку було б неможливим без створення маршруту для нього.


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 000 місцевих значень):

Прапори, Serializable, WebMethod, COMVisible, TypeConverter, Conditional, ThreadStatic, Insolete, InternalsVisibleTo, DebuggerStepThrough.


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;
    }
}
}


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() { }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.