Кратко съдържание



страница49/73
Дата21.07.2018
Размер9.03 Mb.
#76887
1   ...   45   46   47   48   49   50   51   52   ...   73

Упражнения


  1. Обяснете какво представляват делегатите в .NET Framework.

  2. Обяснете какво представляват събитията (events) в .NET Framework.

  3. Какво се препоръчва от утвърдената конвенция за събитията в .NET Framework? Опишете програмния код за дефиниране и използване на събития.

  4. Чрез средствата на делегатите реализирайте универсален статичен метод за изчисляване с някаква точност на безкрайни сходящи редове по зададена функция за общия им член. Чрез подходящи функции за общия член изчислете с точност два десетични знака безкрайните редове:

    • 1 + 1/2 + 1/4 + 1/8 + 1/16 + …

    • 1 + 1/4 + 1/9 + 1/16 + 1/25 + …

    • 1 + 1/2! + 1/3! + 1/4! + 1/5! + …

  1. Напишете клас Person, който описва един човек и съдържа свойствата: име, презиме, фамилия, пол, рождена дата, ЕГН, адрес, e-mail и телефон. Добавете към класа Person за всяко от неговите свойства по едно събитие от системния делегат System.EventHandler, което се активира при промяна на съответното свойство.

  2. Създайте клас PropertyChangedEventArgs, наследник на класа System.EventArgs и дефинирайте в него три свойства – име на променено свойство (string), стара стойност (object) и нова стойност (object) заедно с подходящ конструктор. Създайте делегат PropertyChangedEventHandler за обработка на събития, който да приема два параметъра – обект-изпращач и инстанция на PropertyChangedEventArgs.

  3. Напишете нов вариант на класа Person, който има само едно събитие с име PropertyChanged от тип PropertyChangedEventHandler, което се активира при промяна на някое от свойствата на класа (и съответно се извиква с подходящи параметри).

  4. Изнесете дефиницията на събитието PropertyChanged в отделен интерфейс и променете класа така, че да имплементира интерфейса.

Използвана литература


  1. Светлин Наков, Делегати и събития – http://www.nakov.com/dotnet/ lectures/Lecture-5-Delegates-and-Events-v1.0.ppt

  2. Jeffrey Richter, Applied Microsoft .NET Framework Programming, Microsoft Press, 2002, ISBN 0735614229

  3. Jesse Liberty, Programming C#, O’Reilly, 2001, ISBN 0-596-00117-7

  4. Andrew Whitechapel, Tom Archer, Inside C#, Microsoft Press, 2002, ISBN 0-7356-1648-5

  5. MSDN Training, Programming with the Microsoft® .NET Framework (MOC 2349B), Module 8: Delegates and Events

  6. Julien Couvreur, Curiosity is bliss – http://blog.monstuff.com/archives/ 000040.html

  7. MSDN Library – http://msdn.microsoft.com

Глава 7. Атрибути

Необходими знания


  • Базови познания за архитектурата на .NET Framework

  • Базови познания за общата система от типове в .NET (Common Type System)

  • Базови познания за езика C#

Съдържание


  • Какво представляват атрибутите?

  • Прилагане на атрибути. Атрибути с параметри. Задаване на цел при прилагане на атрибут

  • Къде се използват атрибутите?

  • Дефиниране на собствени атрибути

  • Извличане на атрибути от метаданните

  • Мета-атрибутът AttributeUsage

В тази тема ...


В настоящата тема ще разгледаме какво представляват атрибутите в .NET Framework, как се прилагат и къде се използват. Ще обясним как могат да се дефинират собствени атрибути и да се извличат атрибути от метадан­ните на асемблитата.

Какво представляват атрибутите в .NET?


В повечето езици за програмиране съществуват ключови думи. Такива например са спецификаторите за достъп, които определят областта на видимост на член-променливите на класовете (public, private, protected, ). Най-често компилаторите разпознават само ограничен набор ключови думи и програмистите нямат възможност да дефинират свои собствени.

За компенсиране на тази слабост в .NET Framework се дава възможност програмно да се добавят т. нар. атрибути. Те представляват описателни декларации към типове, полета, методи, свойства и други елементи на кода, подобни на ключовите думи от езиците за програмиране.

Атрибутите позволяват да се добавят собствени описателни елементи (анотации) към кода, написан на C# или на някой от другите езици от .NET платформата, без да се налага промяна в компилатора. По време на компилация те се записват в метаданните на асемблито и при изпълнение на кода могат да бъдат извличани и да влияят на поведението му.

Атрибутите са описателни тагове, които могат да се прилагат към раз­лични елементи от кода, наричани цели. Целите могат да бъдат най-разнообразни: асемблита, типове, свойства, полета, методи, параметри и други елементи от кода.

Декларативна информация се асоциира с програмния код (към типовете, методите, свойствата и т.н.) чрез атрибути. Други приложения могат да извличат тази информация, за да определят как да бъдат използвани елементите, свързани с атрибутите.

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

Атрибутите се делят на две групи – вградени в .NET Framework (които са част от CLR) и дефинирани от програмистите за целите на отделните приложения. Последните се наричат собствени (потребителски) атрибути и най-често се използват в комбинация с reflection (отражение на типо­вете).

Прилагане на атрибути


По-долу ще разгледаме начините, по които можем да приложим атрибут към дадена цел.

За да се приложи атрибут, името му се огражда в квадратни скоби и се поставя непосредствено преди декларацията, за която се отнася. Ето един пример:



// Apply attribute System.FlagsAttribute to FileAccess enum

[Flags]


public enum FileAccess

{

Read = 1,



Write = 2,

ReadWrite = Read | Write

}


В посочения пример системният атрибут Flags (реално това е типът System.FlagsAttribute) е приложен към дефиницията на изброения тип FileAccess и указва, че този изброен тип може да се третира като битово поле, т.е. като множество от битови флагове.

За да бъде приложен атрибут към дадена дефиниция в кода, трябва да се изпълнят следните стъпки:



  1. Да се дефинира нов атрибут или да се използва съществуващ, като неговото пространство от имена (namespace) се импортира в началото на текущия файл от сорс кода.

  2. Да се изпише името на атрибута в квадратни скоби точно преди целта, към която се прилага. По желание могат да му бъдат предадени някакви параметри (инициализиращи данни).

Атрибутите за дадена цел могат да се прилагат и в комбинация. Това става по два начина: като се приложат един след друг или като се изброят със запетаи:

[MyFirstAttribute]

[MySecondAttribute]

public void SomeMethod() { … }
[MyFirstAttribute, MySecondAttribute]

public void SomeMethod() { … }



Двете декларации в горния пример са напълно еквивалентни. Те де­финират публичен метод SomeMethod() и прилагат към него атрибутите MyFirstAttribute и MySecondAttribute.

При прилагането на атрибути суфиксът Attribute може да бъде пропуснат и се подразбира от компилатора. Така следните декларации са еквива­лентни на горните две:



[MyFirst]

[MySecond]

public void SomeMethod() { … }
[MyFirst, MySecond]

public void SomeMethod() { … }



Тъй като атрибутите са класове, при тяхното прилагане може да бъде извикван конструкторът на съответния клас. Ако атрибутът предлага кон­структор без параметри, той може да бъде извикан като се добави () към декларацията. Следователно следващите две декларации са валидни и еквивалентни на предходните две:

[MyFirst()]

[MySecondAttribute()]

public void SomeMethod() { … }
[MyFirstAttribute(), MySecond()]

public void SomeMethod() { … }



От примерите виждаме, че има много синтактично валидни начини за прилагане на един и същ атрибут към дадена цел. За компилатора няма значение кой от тези варианти е употребен, но препоръката е да се използва този без суфикс Attribute, без изброяване със запетаи и без скоби (). За нашия пример препоръчителен е следният запис:

[MyFirst]

[MySecond]

public void SomeMethod() { … }

Атрибутите са обекти


Атрибутите в .NET Framework реално представляват .NET обекти (инстан­ции на клас, наследник на системния клас System.Attribute). Като таки­ва те могат да имат един или няколко конструктора (вкл. конструктор по подразбиране), публични и частни полета, свойства и др. членове. Най-често атрибутите дефинират конструктори, публични полета и свой­ства, които използват за съхраняване на данните, подавани им като пара­метри по време на инициализация.

Всички атрибути в .NET Framework задължително наследяват класа System.Attribute (или негов наследник). Както ще видим по-долу, при дефиниране на собствени (потребителски атрибути) ние също трябва да наследяваме този клас.


Параметри на атрибутите


Някои атрибути могат да приемат параметри. Параметрите биват два вида: позиционни и именувани. Позиционните пара­метри се подават с оп­ределена последователност и се инициализират от конструктора на атри­бута, докато именуваните се подават в произволен ред и задават стойност на свойство или публично поле. Ето един пример:

[DllImport("user32.dll", EntryPoint="MessageBox")]

public static extern int ShowMessageBox(int hWnd, string text,

string caption, int type);

...


ShowMessageBox(0, "Some text", "Some caption", 0);

В примера е използвана комбинация между позиционни и непозиционни параметри. За да бъде приложен към метаданните в асемблито, атрибутът [DllImport] (System.Runtime.InteropServices.DllImportAttribute) по време на ком­пилация се инстанцира и инициализира от компилатора по следния начин:

  1. Създава се обект от класа System.Runtime.InteropServices. DllImportAttribute.

  2. В конструктора му се подава като позиционен параметър стойност "user32.dll".

  3. В публичното му поле EntryPoint се записва стойност "MessageBox".

Преди да бъдат записани в метаданните на съответното асембли, атрибу­тите се инициализират посредством подадените им параметри, с които се задават стойности за техните полета и свойства. При съхраняване в асем­блито атрибутите запазват състоянието си.

На по-късен етап, когато атрибутите бъдат извлечени от метаданните на асемблито, стойностите на техните полета и свойства се извличат заедно с тях и могат да бъдат изпол­звани от програмиста.


Задаване на цел към атрибут


Атрибутите в .NET Framework могат да се прилагат към различни цели, например асембли, клас, интерфей­с, член-променлива на тип и др. Възможните цели на атрибутите се дефинират от изброения тип AttributeTargets както следва:

Име на целта

Употреба (прилага се към)

Assembly

самото асембли

Module

текущия модул

Class

клас

Struct

структура

Interface

интерфейс

Enum

изброен тип

Delegate

делегат

Constructor

конструктор

Method

метод

Parameter

параметър на метод

ReturnValue

връщаната стойност от метод

Property

свойство

Field

поле (член-променлива)

Event

събитие

All

всички възможни цели

При прилагане на атрибут целта обикновено се подразбира. Например, ако поставим атрибут преди декларацията на даден метод, той ще се отнася за съответния метод.

Понякога не може да се използва целта по подразбиране, например ако искаме да приложим атрибут към асемблито. В такива случаи целта може да се зададе преди името на атрибута, отделена от него с двоеточие:



// The following attributes are applied to the target "assembly"

[assembly: AssemblyTitle("Attributes Demo")]

[assembly: AssemblyCompany("DemoSoft")]

[assembly: AssemblyProduct("Entreprise Demo Suite")]

[assembly: AssemblyCopyright("(c) 1963-1964 DemoSoft")]

[assembly: AssemblyVersion("2.0.1.37")]


[Serializable] // The compiler assumes [type: Serializable]

class TestClass

{

[NonSerialized] // The compiler assumes [field: NonSerialized]



private int mStatus;

...


}

Както се вижда от коментарите в кода, за някои от атрибутите целта се задава експлицитно, а за други тя се подразбира.



Сподели с приятели:
1   ...   45   46   47   48   49   50   51   52   ...   73




©obuch.info 2024
отнасят до администрацията

    Начална страница