c# hicheelin lekts

93

Click here to load reader

Upload: -

Post on 19-Jun-2015

1.308 views

Category:

Education


22 download

TRANSCRIPT

Page 1: C# hicheelin lekts

C# хичээлийн лекцүүд

Лекц 1. Сэдэв: .NET Framework ба C# хэл

Дэд сэдвүүд 1.1. .NET Платформ 1.2. .NET Фрэймворк 1.3. Хөрвүүлэлт ба MSIL 1.4. C# хэл 1.5. Класс, Объект, Төрөл 1.6. Програмаа хөрвүүлэх, ажиллуулах

1.1 .NET Платформ 2000 оны 7 сард Microsoft .NET платформыг албан ёсоор зарласан байна үүнтэй хамт C# хэл зарлагдсан юм. .NET платформ нь 1990-ээд оноос хойших Microsoft-н гаргасан олон технологиудыг нэг дор авчирсан, шинэлэг програмчлалын интерфэйсүүдээр тоноглогдсон шинэ хөгжүүлэлтийн орчин болсон юм. Үүнд COM+ сервисүүд, ASP вэб хөгжүүлэлт, XML болон объект хандлагат дизайн, мөн SOAP, WSDL, UDDI зэрэг шинэ вэб үйлчилгээний протоколуудыг дурдаж болно. Платформ нь 4 тусдаа бүтээгдэхүүний бүлгээс тогтддог. Үүнд:

• Хөгжүүлэлтийн орчин: C#, J#, Visual Basic.NET зэрэг хэлүүд; Хөгжүүлэх хэрэгсэл: Visual Studio.NET; Веб үйлчилгээ, виндоуз орчны програмууд хийхэд зориулагдсан баялаг классын сан; Объектуудыг ажиллуулах Common Language Runtime (CLR). Эдгээр нь бүхэлдээ платформын томоохон хэсэг юм.

• Веб үйлчилгээ: Худалдааны вэб үйлчилгээнүүдийг хөгжүүлэх боломж олгоно, мөн програм бүтээхэд нэг хэсэг нь болон ашиглагдаж болно

• Тусгай серверүүд: B2B худалдаа (Business-To-Business) худалдаа, и-мэйл, өгөгдлийн менежмент зэрэгт тусгайлан зориулагдсан BizTalk, Exchange, SQL Server зэрэг сервер системүүд

• Төхөөрөмж: .NET нь үүрэн утаснаас эхлээд тоглоомын төхөөрөмжүүд хүртэлх PC-бус төхөөрөмжүүд дээр ажиллаж чадна

1.2 .NET Фрэймворк

.NET фрэймворк нь үйлдлийн системийн дээд талд ажиллах ба үйлдлийн систем нь Windows ангиллын ямар ч үйлдлийн систем байж болно. Мөн .NET систем нь онолын хувьд өөр үйлдлийн системүүд дээр ажиллах боломжтой, тухайлбал Linux, MAC, Solaris зэрэг. Энэ чиглэлээр MONO нэртэй төсөл амжилттай хийгдэж байна. Вэб хаяг нь http://www.mono-project.com/Main_Page.

Зураг1-1 .NET системийн архитектур

‐1‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 2: C# hicheelin lekts

C# хичээлийн лекцүүд

.NET фрэймворкын хамгийн чухал гишүүн бол CLR (Common Language Runtime) юм, CLR нь програм ажиллах орчин болж өгдөг. CLR ийг Java виртуаль машинтай адилхан гэж ойлгож болно. Виртуаль машин гэдэг нь компьютерийн платформ болон хэрэглэгчийн програмын хооронд хиймэл орчинг бүрдүүлж харилцан ажиллах боломж олгодог системийн програм юм. CLR нь объектуудыг идэвхжүүлж, тэдгээр дээр шалгалт хийж, санах ойд ачаалж, ажиллуулж, мөн тэдний ашиглахгүй орхисон санах ойн үлдэгдэлүүдийг нь цэвэрлэж байдаг. .NET фрэймворк нь дараахь хэсгүүдээс бүрддэг:

1• Үндсэн хэлүүд : C#, J#, VB.NET, Managed C++, JScript.NET • CLR - энэ нь дээрх бүх хэлүүд хоорондоо хамтран ашиглах Windows болон Веб

хөгжүүлэлтэд зориулсан объект хандлагат платформ юм. • Framework Class Library (FCL) гэж нэрлэгдэх хоорондоо хамаарал бүхий

классуудын сан. .NET нь хэлний эрх чөлөөнөөс гадна хэлний нэгдмэл байдлыг хангадаг. Энэ нь өөр өөр хэл дээр бичигдсэн классуудын хооронд удамшуулах, алдаа барих, полиморф хийх давуу талтай юм. Энэ боломжийг Common Type System (CTS) гэж нэрлэгдэх тодорхойлолтын тусламжтайгаар бий болгодог. Тухайлбал, .NET дэх бүх зүйл нь System.Object гэж нэрлэгдэх язгуур классын объектууд юм. CTS нь класс, интерфэйс, төлөөлөгч2 3, заалт төрөл , үндсэн төрөл зэрэг ерөнхий ухагдахуунуудыг өөртөө агуулдаг. Мөн .NET нь хэл хоорондын нэгдмэл байдлыг хангахад зориулагдсан Common Language Specification (CLS)-г өөртөө агуулдаг. CLS нь .NET хэл байх хамгийн доод

                                                 1 Мөн CLR дээр ажиллах COBOL, Python, Fortran, Smalltalk зэрэг олон тооны хэлүүд бий болсон 2 delegate төрөл, C хэлний функцийн заагчтай төстэй 3 reference type – C# дахь бүх объектууд нь заалт төрөлд хамаарна  

‐2‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 3: C# hicheelin lekts

C# хичээлийн лекцүүд

шаардлагуудыг тодорхойлсон байдаг. FCL нь CLS-тэй тохирдог ямар ч хэлнээс ашиглаж болох классуудыг агуулсан сан юм. .NET Фрэймворкын үндсэн классуудын санг Framework Class Library (FCL) гэх ба энэ нь түүхэнд байсан томоохон классын сангуудын нэг болох юм. 5000-аас илүү тооны классуудыг өөртөө агуулсан FCL нь дэсктоп, клиент/сервер, вэб үйлчилгээ болон бусад програм хангамжуудыг хөгжүүлэх ажлыг үлэмж хөнгөвчилдөг. FCL-н доод түвшин болох үндсэн классуудын сан нь үндсэн оролт/гаралт, тэмдэгт мөр боловсруулалт, хамгаалалтын менежмент, сүлжээний холболтууд, параллель боловсруулалт, өгөгдлийн бүтцийн үйлдлүүд зэргийг дэмждэг. Үүний дээрх давхарга нь өгөгдлийн менежмент, XML боловсруулалтыг дэмжих зорилгоор үндсэн суурь классуудыг өргөтгөсөн классууд юм. Классууд нь стандарт SQL хэлээр дамжуулан өгөгдлийг удирдах боломж олгодог, энэ классуудын олонлогыг ADO.NET гэж нэрлэдэг. Мөн XML өгөгдөл боловсруулах, XML хайлт хийх боломжтой классууд байдаг. Өгөгдлийн болон суурь классуудыг өргөтгөж гурван өөр технологиор програм хөгжүүлэхэд зориулж тоноглосон байна: Web Services, Web Forms, Windows Forms. Вэб үйлчилгээний сан нь firewall болон NAT програмын асуудал тулгарсан ч ажиллах чадвартай, сүлжээний орчны авсаархан үйлчилгээнүүдийг хөгжүүлэхэд зориулсан классуудыг агуулна. Вэб үйлчилгээнүүд нь HTTP болон SOAP протоколуудыг холболтдоо ашигладаг учраас энэ нь сүлжээний орон зайд чөлөөтэй ажиллах боломжтой болгодог. Web Forms болон Windows Forms сангууд нь веб болон виндоуз орчны програм хангамжуудыг Хурдан Хугацаанд Хөгжүүлэх (Rapid Application Development) боломж олгоно. Контролуудыг зүгээр л чирч тавих замаар програмын цонхон дээр оруулж, double-click хийж харгалзах үзэгдэл боловсруулалт хийх кодыг бичнэ.

1.3 Хөрвүүлэлт ба MSIL

.NET-д програмууд нь машины биелэгдэх код руу хөрвүүлэгддэггүй, харин Microsoft Intermediate Language (MSIL) код руу хөрвүүлэгддэг, энэ нь CLR-аар ажиллах боломжтой тусгай код4 юм. C# хэлний үүсгэдэг MSIL (ихэвчлэн IL гэж товчилдог) нь өөр хэлнүүдийн үүсгэдэг IL файлтай ижилхэн байдаг. Үүний ачаар .NET нь хэл хамааралгүй платформ болж чаддаг. Програмаа хөрвүүлэх үед C# код нь IL руу хөрвүүлэгддэг. IL нь диск дээр файлд хадгалагдана. Програмаа ажиллуулах үед IL код нь Just In Time (JIT) хөрвүүлэгчээр дахин хөрвүүлэгддэг (энэ процессыг ихэвчлэн JIT’ing гэж хэлдэг). Үр дүнд нь машины код гарч машины процессор үүнийг биелүүлдэг байна. Стандарт JIT хөрвүүлэгч нь идэвхжихэд бэлэн горимд ажилладаг. Програм дуудагдсан үед JIT хөрвүүлэгч нь IL код дээр шинжилгээ хийгээд дараа нь машинтай зохицон маш хурдтай ажиллах машины кодыг үүсгэдэг. JIT хөрвүүлэгч нь програм ажиллаж байх үед код хөрвүүлэгдсэн эсэхийг таних чадвартай учраас шаардлагатай үед л хөврүүлэлт хийгддэг. .NET програм ажиллахдаа урьдчилан-хөрвүүлэгдсэн кодыг дахин ашиглаж улам хурдтай ажиллахыг тэмүүлдэг байна.

     Боловсруулсан: ММЗТ-н багш Б.Болормаа

                                                 4 Java байт кодтой төстэй

‐3‐ 

Page 4: C# hicheelin lekts

C# хичээлийн лекцүүд

Ассемблай гэдэг нь IL кодыг агуулсан Dynamic Link Library (DLL) эсвэл биелэх файлыг (EXE) хэлнэ. Ассемблай бол програмын дахин ашиглагдах (reuse), хувилбарлах (versioning), нууцлах (security), зөөвөрлөн байршуулах (deployment) үндсэн нэгж нь юм. CLR нь ассемблайг удирдах классуудыг мөн өөртөө агуулдаг. 1.4 C# хэл C# бол шинэ хэл юм, гэхдээ сүүлийн хэдхэн жилийн дотор маш олон програм зохиогчдын сонирхолыг татаж чадсан хэл юм. Энэ хэл нь маш энгийн бөгөөд ердөө 80 түлхүүр үг, 12 үндсэн өгөгдлийн төрөлтэй. Тийм боловч C# нь орчин үеийн програмчлалын асуудлуудыг шийдэхэд маш тохиромжтой, үр бүтээмж өндөртэй хэл юм. C# нь C++ болон Java хэлнээс удамшин үүссэн бөгөөд объект хандлагат, компонентод суурилсан, бүтцийн програмчлалуудыг дэмждэг. C# хэлийг Microsoft-н инженерүүд болох Anders Hejlsberg, Scott Wiltamuth нараар удирдуулсан цомхон баг хөгжүүлсэн юм. Hejlsberg нь хамгийн түгээмэл PC хэл болох Turbo Pascal хэлийг үүсгэгчдийн нэг бөгөөд мөн Borland Delphi хэлийг хөгжүүлсэн багийг удирдаж байсан юм. C# програм бичиж эхлэх

‐4‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 5: C# hicheelin lekts

C# хичээлийн лекцүүд

Уламжлалт “Hello World” програмаа бичиж эхлэе. Доорх жижигхэн програмаар C# хэлний түлхүүр онцлогуудыг гаргахыг оролдоё. class HelloWorld { static void Main() { // системийн консоль объектыг ашиглаж байна System.Console.WriteLine(“Hello World”); } } HelloWorld –г хөрвүүлээд ажиллуулахад “Hello World” гэсэн текстийг консоль (текст командын горимд ажилладаг) дээр харуулна. Энэ жижигхэн програм дээр илүү дэлгэрэнгүй цааш авч үзэе. 1.5 Класс, Объект, Төрөл Объект хандлагат програмчлалын үндэс суурь бол шинэ төрлүүдийн үүсэн бий бололт юм. Төрөл гэдэг нь нэг зүйл юм. Зарим тохиолдолд зүйл гэдэг нь өгөгдлийн хүснэгт, thread гэх мэт хийсвэр, зарим тохиолдолд цонхон доторх товчлуур гэх мэт бодитой байдаг. Төрөл нь зүйлүүдийн ерөнхий нийтлэг шинж чанар (property), авирыг (behavior) тодорхойлдог. Жишээлбэл, програмд Help, Ok, Cancel гэсэн гурван товчлууртай гэж бодоё. Эдгээр тус бүрдээ өөрийн хэмжээ, байрлал, гарчигтай. Мөн бүгд зурагдах, идэвхжих, дарагдах гэх мэт нийтлэг авиртай. Иймээс хэдийгээр бие биенээсээ ялгагдах боловч эд бүгдээрээ нэг төрлийнх юм. Объект хандлагат прорамчлалын хэлэнд байдаг шиг C# -д төрөл нь классаар тодорхойлогддог. Классын төлийг5 нь объект гэж нэрлэдэг. “Hello World” програмд нэг төрөл тодорхойлогдсон байна, тэр нь HelloWorld класс юм. C#-д төрлийг классаар тодорхойлох ба class гэсэн түлхүүр үгийг ашигладаг, тэгээд нэр өгнө - энэ тохиолдолд нэр нь HelloWorld, дараа нь түүний шинжүүд, авируудыг тодорхойлдог.

Методууд

Класс нь шинж чанар, авир хоёуланг өөртөө агуулдаг. Авир нь түүний гишүүн методуудаар тодорхойлогддог. Шинж чанарыг дараагийн сэдвээр авч үзэе. Метод гэдэг нь класс доторх функц юм. Заримдаа методыг гишүүн функц гэж нэрлэдэг. Методууд WriteLine(), AddNumbers() гэх мэт нэртэй байна. Дээрх жишээнд класс нь Main() гэж нэрлэгдэх тусгай нэртэй методыг агуулсан байна, энэ тодорхойлолт нь классын үндсэн буюу эхний метод юм шүү гэдгийг CLR-д хэлж өгдөг. Програм ажиллаж эхлэхэд CLR нь Main() функцийг дууддаг. C# програм болгон Main() методтой байх ёстой. Зарчмын хувьд програмд хэд хэдэн Main() метод байж болох ба /main директивыг ашиглан аль классын Main() метод нь тухайн програмын эхлэх цэг болох вэ гэдгийг зааж болно.

                                                 5 Instance – Төл, нэг хувь, нэг хуулбар

‐5‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 6: C# hicheelin lekts

C# хичээлийн лекцүүд

Метод тодорхойлолт нь дараахь байдалтай. int myMethod(int size); Энэ тодорхойлолт нь myMethod нэртэй метод size хувьсагчаар дамжуулан нэг параметерийг хүлээн авах ба бүхэл тоон утгыг үр дүн болгон гаргана гэдгийг хэлж байна. Зарим методууд үр дүн буцаадаггүй, энэ тохиолдолд түүнийг void буцааж байна гэж хэлдэг. Жишээ нь: void myVoidMethod( );

Тайлбар хийх

C# програм дотор мөн тайлбар бичигдэж болно. // системийн консоль объектыг ашиглаж байна Хоёр налуу зураасаар эхэлсэн мөр нь тайлбар гэдгийг илэрхийлдэг. Тайлбар нь програм зохиогчийн бичсэн тэмдэглэгээ бөгөөд програмын ажиллагаанд нөлөө үзүүлэхгүй. C# хэлэнд тайлбарыг гурван янзаар хийж болно. Эхнийх нь, //-аар эхлээд тухайн мөрийн төгсгөл хүртэл нэг мөр тайлбар байж болно. Хоёр дахь нь, /*-ээр эхлүүлж */ –ээр дуусгаж олон мөр тайлбар хийж болно. Гурав дахь нь, кодыг XML дээр суурилсан баримттай холбож тайлбар хийх боломжтой байдаг. Үүнийг дараа үзнэ.

Консоль програм

“HelloWorld” програм нь консоль ангиллын програм юм. Консоль програм нь товч, сонголт зэрэг хэрэглэгчийн график интерфэйс байхгүй, зөвхөн текст өгөгдөл оруулах, гаргах үйлдлүүд хийгддэг програм юм (MS-DOS програмуудтай төстэй). Дээрх програмд консоль руу гаралт нь Console классаар хийгдэж байна, Console класс нь стандарт гаралт рүү текстийг хэвлэх WriteLine() методтой байдаг. Методыг дуудахдаа (.) цэг үйлдлийг ашиглана.

Нэрмуж

.NET системийн классын санд ArrayList, Dictionary, Event гэх мэт хэдэн арав, хэдэн зуун мянган нэрсүүд байдаг. Эдгээр нэрсийг ялгахад асуудал үүсдэг. Програм зохиогч тэдгээр нэрсийг бүгдийг нь санаж чадахгүй, мөн аль нэг нэртэй нь ижил нэртэй өөрийн гэсэн классыг үүсгэх үед асуудал гарна. Тухайлбал, програм зохиогч өөрийн Dictionary нэртэй классыг үүсгэхийг хүсэж болно, гэтэл энэ нь .NET-д байдаг Dictionary классын нэртэй зөрчил үүсгэнэ, учир нь класс бүр үл давхардах нэртэй байх ёстой байдаг.

6Үүнийг шийдэх шийдэл нь нэрмуж юм. Нэрмуж нь тодорхой зүйлсийг нэгэн нэрийн дор хамаатуулан утга учиртай нэрлэх боломж олгодог юм.

     Боловсруулсан: ММЗТ-н багш Б.Болормаа

                                                 6 namespace 

‐6‐ 

Page 7: C# hicheelin lekts

C# хичээлийн лекцүүд

Том, жижиг үсгүүд

C# хэлэнд нэрний үсгийн том, жижиг нь ялгаатай, ө.х writeLine ба WriteLine нь ялгаатай юм. Тиймээс програмын код дахь хувьсагч, функц, тогтмолын нэрсүүдийг тодорхой дүрмийн дагуу нэршиж занших нь зүйтэй.

static түлхүүр үг

Өмнөх жишээн дэх Main() методод өөр нэг шинж ажиглагдаж байна, энэ нь static гэсэн түлхүүр үгээр эхэлсэн байна. static түлхүүр үг нь Hello объектыг эхэлж үүсгэлгүйгээр Main() методыг дуудаж болно гэдгийг илэрхийлнэ.

Програмаа хөрвүүлэх, ажиллуулах

“HelloWorld” програмыг хөрвүүлэх олон арга байна. Нэг бол Visual Studio.NET хөгжүүлэлтийн хэрэгслийн тусламжтай хөрвүүлж болно. Эсвэл C#-ийн командын мөрний хөрвүүлэгчийг ашиглан дараахь байдлаар хөрвүүлж болно.

1. Програмаа hello.cs нэртэйгээр хадгална 2. Командын цонхыг нээнэ (Start->Run гээд cmd гэж бичнэ) 3. Командын мөр дээр дараахь командыг бичнэ. (хөрвүүлэгчийн замыг тодорхойлж

өгөхийн тулд Path хувьсагчид .NET фрэймворкын замыг зааж өгөх хэрэгтэй)

csc hello.cs 4. Програмаа ажиллуулахдаа Hello гэж бичээд ажиллуулна.

JIT (Just In Time) Хөрвүүлэлт

csc командыг ашиглан hello.cs кодыг хөрвүүлэхэд биелэх файл үүснэ. Энэхүү .exe файл нь IL кодыг агуулна гэдгийг санаж байх хэрэгтэй. Сонирхолтой нь, хэрэв энэ програмыг VB.NET юмуу өөр хэл дээр бичээд хөрвүүлэхэд адилхан IL үүсэх болно. Өөр хэлнүүдээс үүссэн IL нь бараг ялгагдах боломжгүй байдаг. Хөрвүүлэгч нь IL код дээр нэмээд стандарт Win32 биелэх файлын толгойг .exe файлын зөвхөн-уншигдах хэсэгт оруулдаг.              

‐7‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 8: C# hicheelin lekts

C# хичээлийн лекцүүд

Лекц 2.3 C# хэлний үндэсүүд

Дэд сэдвүүд: • Үндсэн төрлүүд (тогтмол,хувьсагч, илэрхийлэл) • Үйлдлүүд (энгийн, арифметик, жиших, нөхцөлт, логик үйлдэл, үйлдлийн

зэрэглэл) • Заавар

Үндсэн төрлүүд C# хэл нь хатуу төрөлтэй хэл юм. Хатуу төрөлтэй хэлэнд үүсгэж байгаа объект бүрийн төрлийг заавал тодорхой заах ёстой. Ингэснээр хөрвүүлэгч тухайн объектод тохирсон утгыг оноохыг шаарддаг, энэ нь мөн алдаа гаргахаас сэргийлдэг. Өгөгдлийн төрөл нь хөрвүүлэгчид тухайн объектын хэмжээ (жнь, int төрөл нь 4 байт объектыг заана), авируудыг мэдээлдэг (жнь, Button нь зурах, дарах гэх мэт авиртай). C#-ийн төрлүүдийг хоёр ангилалд хуваана: үндсэн төрөл (value type), заалт төрөл (reference type). Үндсэн төрөл болон заалт төрлийн хоорондох ялгаа бол санах ойд утгуудаа яаж хадгалж байгаа арга юм. Үндсэн төрөл нь өгөгдлөө стект хадгалдаг. Заалт төрлийн хувьсагчийн хаяг нь стект байрлана, харин жинхэнэ объект нь хийпэд7 байрладаг. Стек ба Хийп Стек гэдэг нь “эхэлж орсон нь сүүлд гарах“ зарчмаар элементүүдийг хадгалдаг өгөгдлийн бүтэц юм. Энд дурдсан стек нь локаль хувсагчидыг хадгалах санах ойн мужийг хэлж байна. C# хэлэнд үндсэн төрлүүд нь, жишээ нь integer, стект хувиарлагдах бөгөөд хувьсагчийн нэр нь санах ойн хаягаа илэрхийлж байдаг. Заалт төрлүүд нь (жнь, object) хийпэд хувиарлагддаг. Объект хийпэд хувиарлагдах үед түүний хаяг нь буцаагдах ба энэхүү хаяг нь заалт болон хувьсагчид оноогддог.

8Хог цуглуулагч нь объектын зарлагдсан стек хүрээ дууссанаас хойш хэсэг хугацааны дараа тэрхүү объектыг санах ойгоос устгадаг. Стек хүрээ гэдэг нь үндсэндээ функцүүдээр тогтоогддог. Тухайлбал, функц дотор локаль хувьсагч зарлавал уг функ ажиллаж дууссаны дараа үлдэгдэл цуглуулагч түүнийг устгах ёстой гэдгийг ойлгох болно. Хийп дэх объектуудын хувьд түүнийг зааж байгаа хамгийн сүүлийн заалт устсанаас хойш хэсэг хугацааны дараа уг объект үлдэгдэл цуглуулагчаар устгагддаг. C# хэлэнд орчин үеийн хэлэнд байвал зохих бүх үндсэн төрлүүд байдаг бөгөөд эдгээр нь харгалзан .NET CLS төрөл рүүгээ бууж байдаг. C# төрлийг .NET рүү харгалзуулсан буулгалт нь C# дээр үүсгэгдсэн объект өөр хэл дээр үүсгэгдсэн объекттой харилцан ажиллах боломжийг олгодог.

                                                 7 Heap – санах ойн нэг төрлий н муж 8 Garbage collector 

‐8‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 9: C# hicheelin lekts

C# хичээлийн лекцүүд

Төрөл бүр санах ойд тогтмол хэмжээ эзэлдэг. Төрөл Хэмжээ(байт) .NET төрөл Тодорхойлолт byte 1 Byte Байт, 0-255 char 1 Char Юникод тэмдэгт bool 1 Boolean true эсвэл false sbyte 1 Sbyte Тэмдэгтэй байт, -128 - 127 short 2 Int16 Бага бүхэл тоо (-32768 - 32767)

     Боловсруулсан: ММЗТ-н багш Б.Болормаа

ushort 2 Uint16 Тэмдэггүй бага бүхэл тоо, 0 -ээс 216-1 int 4 Int32 Бүхэл тоо -(231-1) –ээс (231-1) uint 4 Uint32 Тэмдэггүй бүхэл тоо, 0 -ээс 232-1 float 4 Single Бодит тоо, ±1.5*10-45 ээс ±3.4*1038 double 8 Double Давхар нарийвчлалтай бодит тоо, ±5.0*10-324 ээс

±1.7*10308 decimal 8 Decimal 28 хүртэл цифртэй, тогтмол нарийвчлалтай бутархай

тоо. Энэ нь ихэвчлэн санхүүгийн тооцоололд ашиглагддаг. “m” эсвэл “M” гэсэн дагаваруудыг хэрэглэдэг.

long 8 Int64 Их бүхэл тоо, -9,223,372,036,854,775,808 ээс 9,223,372,036,854,775,807

ulong 8 Uint64 Тэмдэггүй их бүхэл тоо, 0 ээс 0xffffffffffffffff Эдгээр үндсэн төрлүүдээс гадна C# хэлэнд enum ба struct гэсэн үндсэн төрлүүд байдаг.

Үндсэн төрлөөс сонгож хэрэглэх

Ерөнхийдөө ямар хэмжээтэй бүхэл тоон төрөл (short, int эсвэл long) сонгох вэ гэдэг нь ямар хэмжээтэй өгөгдөл хадгалах вэ гэдгээс хамаарна. Жишээлбэл, ushort төрөл нь 0-ээс 65535 хүртэлх тоон утгыг хадгалж чадна. Санах ой хангалттай байгаад онцын өөр шалтгаан байхгүй бол int төрлийг ихэнх тохиолдолд хэрэглэх нь зүйтэй.

Тогтмол ба Хувьсагч

Хувьсагч гэдэг нь тодорхой төрөл бүхий санах ойн хадгалах үүр юм. Хувьсагчид утга оноож болно мөн тэрхүү утга нь програмын ажиллах үед өөрчлөдөнө. Хувсагчийг зарлахдаа түүний төрөл, нэрийг зааж өгөх ёстой. Хувьсагчийг зарлах үед түүнд анхны утгыг оноож өгч болно. class Values { static void Main( ) { int myInt = 7;

System.Console.WriteLine("Initialized, myInt: {0}", myInt); myInt = 5; System.Console.WriteLine("After assignment, myInt: {0}", myInt);

} } Энэ жишээн дээр myInt хувьсагчийг зарлах үедээ түүнд 7 гэсэн анхны утга оноож байна, тэгээд түүний утгыг хэвлээд дараа нь 5 гэсэн утгыг дахин оноож дахин хэвлэж байна.

‐9‐ 

Page 10: C# hicheelin lekts

C# хичээлийн лекцүүд

WriteLine( ) Дээрх жишээнд WriteLine методын өөр нэг хэлбэрийг ашигласан байна. Энэ жишээнд WriteLine метод нь 2 параметр хүлээн авах ба эхний параметр нь өгөгдлийг хэвлэх форматыг “Initialized, myInt: {0}” хэлбэртэй гэж тодорхойлно, хоёр дахь нь хэвлэгдэх хувьсагчийн нэр. Энд {0} бичиглэл нь эхний хувьсагч гэдгийг заана. C# хэл нь хувьсагчийн ашиглахын өмнө заавал утга оноосон байхыг шаардана. Энэ дүрмийг шалгахын тулд myInt хувьсагчид утга оноолгүйгээр дээрх жишээг өөрчилж үзэж болно. class Values { static void Main( ) { int myInt;

System.Console.WriteLine("UnInitialized, myInt: {0}", myInt); myInt = 5; System.Console.WriteLine("Assigned, myInt: {0}", myInt);

} } Энэ програмыг хөрвүүлэх үед C# хөрвүүлэгч дараахь алдааг заана. values.cs(6,55): error CS0165: Use of unassigned local variable 'myInt' Тэгэхээр програм дахь хувьсагч бүрийг зарлахдаа анхны утга оноох ёстой юу? Үгүй, заавал анхны утга оноох хэрэггүй, гэхдээ заавал ашиглахын өмнө утга оноосон байх хэрэгтэй гэсэн үг. class Values { static void Main( ) { int myInt; myInt = 7;

System.Console.WriteLine("UnInitialized, myInt: {0}", myInt); myInt = 5; System.Console.WriteLine("Assigned, myInt: {0}", myInt);

} }

Нэр

Хувьсагч нь нэртэй байх бөгөөд нэр нь үсгээр эсвэл доогуур зураасаар эхлэх ёстой. Нэрэнд үсгийн том, жижиг нь ялгаатай байдаг, myVariable ба MyVariable нэрнүүд нь ялгаатай юм. C# хэлэнд өөрийн гэсэн тогтсон нэрлэх дүрэм байдаг, хувьсагчдын хувьд Камель тэмдэглэгээ (жнь, someVariableName), метод болон бусад нэрнүүдийн хувьд Паскаль тэмдэглээг (жнь, SomeFunction) ашигладаг. Камель ба Паскаль тэмдэглээний ялгаа гэвэл Паскаль тэмдэглэгээнд нэр нь том үсгээр эхэлдэг.

‐10‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 11: C# hicheelin lekts

C# хичээлийн лекцүүд

Нэр нь түлхүүр үгтэй адил байж болохгүй. Ө.х int эсвэл class гэсэн нэртэй хувьсагчид байж болохгүй.

Тогтмол

Тогтмол гэдэг бол түүний утгыг нь өөрчлөх боломжгүй хувьсагч юм. Зарим тохиолдолд хувьсагчийн утга өөрчлөгдөхгүй байх хэрэгцээ гардаг. Тогтмол нь 3 хэлбэрээр байж болно: эх хэлбэрээрээ, нэрлэсэн тогтмол, тоочсон тогтмол. x = 32; Энд 32 гэсэн тоо нь эх хэлбэрээрээ байгаа тогтмол юм. Ө.х 32-н утга бол үргэлж 32 байна, 32-д шинэ утга оноож чадахгүй, өөрчилж чадахгүй. Нэрлэсэн тогтмол нь тогтмол утгад нэр оноосон хэлбэр юм. Дараахь байдлаар ийм тогтмолыг зарлаж болно. const type identifier = value; Тогтмол нь зарлагдах үедээ анхны утга нь оноогдсон байх ёстой. const int FreezingPoint = 32; Энд 32 нь эх хэлбэрээрээ байгаа тогтмол, FreezingPoint нь нэрлэсэн тогтмол юм. using System; class Values { static void Main( ) {

const int FreezingPoint = 32; // degrees Farenheit const int BoilingPoint = 212; Console.WriteLine("Freezing point of water: {0}", FreezingPoint ); Console.WriteLine("Boiling point of water: {0}",BoilingPoint ); //BoilingPoint = 21;

} }

Тоочсон тогтмол

Тоочих төрөл нь тогтмолын өөр нэг хувилбар юм. Тоочих төрөл нь тодорхой тооны нэрлэсэн-тогтмолуудын олонлог юм. Өмнөх жишээн дэх const int FreezingPoint = 32; const int BoilingPoint = 212; тогтмолууд дээр const int LightJacketWeather = 60; const int SwimmingWeather = 72;

‐11‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 12: C# hicheelin lekts

C# хичээлийн лекцүүд

const int WickedCold = 0; тогтмолуудыг нэмэх хэрэгтэй гэж үзэе. C#-д enum тоочих төрөл нь энэ боломжийг олгоно. enum Temperatures { WickedCold = 0,

FreezingPoint = 32, LightJacketWeather = 60, SwimmingWeather = 72, BoilingPoint = 212,

} Ерөнхийдөө, тоочсон тогтмолыг зарлах хэлбэр нь дараахь байдалтай. [attributes] [modifiers] enum identifier [:base-type] {enumerator-list}; attributes, modifiers –н тухай дараа үзнэ. base-type нь тухайн тоочилтын суурь төрөл нь юм. Хэрэв энэ заалтыг орхивол тухайн тоочсон утгуудыг integer байна гэж ойлгодог. Мөн бусад тоон төрлүүдийг ашиглаж болно. Жишээ нь, ushort, uint enum ServingSizes :uint {

Small = 1, Regular = 2, Large = 3

} Тоочих төрөл дэх тогтмол бүр түүнд харгалзах тоон утгатай байдаг, хэрэв энэ утгыг зааж өгөхгүй бол 0-ээс эхлэн дараалуулан автоматаар өмнөх утга дээр нэгийг нэмсэн утга олгогдох болно. Жишээ нь: enum SomeValues {

First, Second, Third = 20, Fourth

} Энд First=0, Second=1, Third=20, Fourth=21 болох юм. Тоочих төрөл нь хийсвэр төрөл юм, тиймээс тоочих төрөл болон бүхэл тоон төрлийн хооронд хөрвүүлэлт хийх бол ил хөрвүүлэлт хийхийг шаарддаг.

Тэмдэгт мөр тогтмол

Мөр тогтмол нь тэмдэгтүүдийн дараалал юм. Тэмдэгт мөр төрлийн хувьсагчийг string түлхүүр үгээр зарлана. string myString; Тэмдэгт мөр утга нь давхар хашилтад хийгдэж бичигдэнэ:

‐12‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 13: C# hicheelin lekts

C# хичээлийн лекцүүд

“Hello World” Анхны утга оноосон тэмдэгт мөр төрлийн хувьсагч: string myString = “Hello World”;

Илэрхийлэл

Үр дүндээ утга гаргадаг хувьсагч, тогтмол, объект, үйлдлүүдийн дараалсан нийлэмжийг илэрхийлэл гэдэг. Жишээлбэл, myVariable = 57 нь илэрхийлэл юм. Учир нь энэ нь 57 гэсэн утгыг үр дүн болгон гаргаж байна. Энд (=) тэмдэгт нь утга оноох үйлдэл юм (тэнцүүлэх үйлдэл биш!). myVariable = 57 нь илэрхийлэл учраас өөр илэрхийлэл дотор мөн оролцож болно. mySecondVariable = myVariable = 57; Энэ жишээнд 57 утга myVariable хувьсагчид оноогдож байна, энэ олголтын үр дүн нь дахиад хоёр дахь хувьсагч болох mySecondVariable-д оноогдож байна. Илэрхийлэлд илүү сул зайнуудыг оруулж болно. Жишээлбэл, myVariable = 5;эсвэл: myVariable = 5; Хөрвүүлэгч нь дээрх хоёр зааврыг адилхан гэж үзнэ. Гэхдээ энэ дүрэм нь тэмдэгт мөр тогтмолын хувьд буруу болох юм. Ө.х “Hello World” ба “Hello World” тэмдэгт мөрүүд нь ялгаатай. Сул зайг ихэвчлэн програмыг уншихад илүү ойлгомжтой болгох зорилгоор ашигладаг, хөрвүүлэгчийн хувьд энэ нь ялгаагүй зүйл.

Үйлдэл

Энгийн тооцоолол хийхэд олгох, нэмэх, хасах гэх мэт олон үйлдлүүдийг ашигладаг.

Олгох үйлдэл (=)

Энэ тэмдэгт нь олгох үйлдлийг төлөөлөх ба зүүн талд байгаа хувьсагчид баруун талд байгаа утгыг олгоход хэрэглэгддэг.

Арифметик үйлдлүүд

C# нь нэмэх (+), хасах (-), үржих (*), хуваах (/), үлдэгдэл олох (%) арифметик үйлдлүүдийг ашигладаг. Хуваах үйлдлийн хувьд бүхэл 2 тоог хуваах үед ногдворын бүхэл хэсэг нь үр дүн болж гарна. Жишээ нь, 17-г 4-д хуваахад үр дүн нь 4 болно (17/4=4 ба 1 үлдэгдэлтэй). Харин бодит тоог хуваах үед үр дүн нь бутархай тоо гарна.

‐13‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 14: C# hicheelin lekts

C# хичээлийн лекцүүд

Үлдэгдэл олох үйлдэл нь мөн тоог ямар нэг тоо өөр тоонд бүхлээр хуваагддаг эсэхийг шалгахад хэрэглэгдэж болно. 80 % 10 = 0 учраас 80 нь 10-д бүхлээр хуваагдана.

Тооцоолоод олгох үйлдэл

mySalary хувьсагчийн утгыг 5000-аар нэмэгдүүлэх хэрэгтэй гэж бодоё. Үүнийг mySalary = mySalary + 5000; эсвэл mySalary += 5000; гэж бичиж болно. C#-д тооцоолол хийгээд гарсан үр дүнг нь олгодог += (нэмээд олгох), -= (хасаад олгох), *= (үржээд олгох), /= (хуваагаад олгох), %= (үлдэгдэл олгох) операторууд байдаг. Хувьсагчийн утгыг 1-ээр нэмэгдүүлэх, хорогдуулах шаардлага олонтаа тохиолддог, үүнд зориулж ++, -- үйлдлүүд бий. Жишээлбэл, myAge++; firstValue = secondValue++; гэж хэрэглэж болно. Эдгээр үйлдлүүдийг олгох үйлдэлтэй хамт хэрэглэсэн үед хувьсагчийн утгыг 1-ээр нэмсэний дараа нөгөө хувьсагчид гарсан үр дүнг олгох уу, эсвэл олгосны дараа нь 1-ээр нэмэгдүүлэх үү гэсэн асуулт гарна. Үүнийг шийдэхэд угтвар (prefix), дагавар (postfix) бичиглэлүүдийг хэрэглэнэ. firstValue = secondValue++; // postfix firstValue = ++secondValue; // prefix Угтвар, дагавар операторуудын ялгааг ойлгохын тулд дараахь жишээг харая. using System; class Values { static void Main( ) {

int valueOne = 10; int valueTwo; valueTwo = valueOne++; Console.WriteLine("After postfix: {0}, {1}", valueOne, valueTwo); valueOne = 20; valueTwo = ++valueOne; Console.WriteLine("After prefix: {0}, {1}", valueOne, valueTwo);

} } Гарах үр дүн: After postfix: 11, 10 After prefix: 21, 21

‐14‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 15: C# hicheelin lekts

C# хичээлийн лекцүүд

Нөхцөлт үйлдэл

Ихэнх үйлдэл нэг юмуу хоёр илэрхийллийг холбогддог. Харин нөхцөлт үйлдэл нь (?:) гурван илэрхийллийг холбодог. cond-expr ? expr1 : expr2 Энэ үйлдэл нь cond-expr нөхцөлд бичигдсэн илэрхийллийг үнэлээд хэрэв утга нь үнэн бол expr1, худал бол expr2-г үр дүн болгон гаргадаг. class Values { static void Main( ) {

int valueOne = 10; int valueTwo = 20; int maxValue = valueOne > valueTwo ? valueOne : valueTwo; Console.WriteLine("ValueOne: {0}, valueTwo: {1}, maxValue: {2}",

valueOne, valueTwo, maxValue); } } Гаралт: ValueOne: 10, valueTwo: 20, maxValue: 20

Жиших үйлдэл

Жиших үйлдэл нь хоёр утгыг харьцуулаад үнэн эсвэл худал (boolean) утга буцаадаг оператор юм. Жишээ нь, эрс их (>) операторыг 5 > 2 гэж хэрэглэвэл үр дүн нь true, 2 > 5 гэж хэрэглэвэл үр дүн нь false болно. Нэр Оператор Тэнцүүлэх == Тэнцүү биш != Их > Их буюу тэнцүү >= Бага < Бага буюу тэнцүү <=

Логик үйлдэл

9Логик илэрхийллүүдийг холбоход логик үйлдлүүдийг ашигладаг. Нэр Оператор Ба && Эсвэл || Үгүйсгэл ! Жишээ нь, (x==3) && (y==7) энэ логик илэрхийлэл нь (x==3), (y==7) гэсэн хоёр логик илэрхийллээс тогтсон бөгөөд БА (&&) логик үйлдлээр холбогдсон байна. Энэ илэрхийллийн утга нь x нь 3-тай тэнцүү бөгөөд y нь 7-той тэнцүү байх үед үнэн байна.

                                                 9 үнэн эсвэл худал утга гаргадаг илэрхийлэл 

‐15‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 16: C# hicheelin lekts

C# хичээлийн лекцүүд

Богино үнэлэлт Дараахь кодыг авч үзэе. int x=8; ((x==8) || (y==12) ? expr1 : expr2) Энэ илэрхийллийг үнэлэхэд x нь 8-тай тэнцүү учраас үр дүн нь true гарна. Хоёр дахь илэрхийллийг бодох шаардлага байхгүй. Ө.х y нь 12-той тэнцүү байна уу, тэнцүү биш байна уу гэдгээс хамаарахгүй. Мөн дараахь илэрхийллийг авч үзэе. int x=8; ((x==5) && (y==12) ? expr1 : expr2) Энэ тохиолдолд мөн л хоёр дахь илэрхийллийг үнэлэх шаардлагагүй, үр дүн нь false утга гарах юм. Учир нь эхний x==5 илэрхийлэл false утга өгнө (&& үйлдэл нь хоёр утга хоёулаа үнэн үед үнэн гардгийг санаарай). Эдгээр тохиолдлуудад C# хөрвүүлэгч нь богино-үнэлэлт хийдэг, ө.х хоёр дахь илэрхийлэл дээр хэзээ ч үнэлэлт хийгдэхгүй.

Үйлдлийн зэрэглэл

Хөрвүүлэгч нь илэрхийлэл дэх үйлдлүүдийн биелэх дарааллыг мэддэг. Жишээ нь, myVar = 5 + 7 * 3; Энэ илэрхийлэлд * үйлдэл нь + үйлдлээс өмнө үнэлэгдэх ёстой. Ө.х * үйлдэл нь + үйлдлээс өндөр зэрэглэлтэй байна. Мөн нийлмэл илэрхийллүүд дотор хаалт хэрэглэн үйлдлүүдийн үнэлэх дарааллыг өөрчилж болно. Дараахь хүснэгтэд үйлдлүүдийн биелэх дарааллыг тодорхойллоо. Ангилал Үйлдлүүд Үндсэн (x) x.y f(x) a[x] x++ x—new typeof sizeof checked unchecked Унар + - ! ~ ++x —x (T)x Үржих * / % Нэмэх + - Шилжүүлэх << >> Жиших < > <= >= is Тэнцүүлэх == != Бит Ба & Бит XOR ^ Бит Буюу | Логик Ба && Логик Буюу || Гурван байрт ?: Олгох = *= /= %= += -= <<= >>= &= ^= |=

3. Заавар

‐16‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 17: C# hicheelin lekts

C# хичээлийн лекцүүд

Зааварууд нь ямар боловсруулалт хийхийг компьютерт зааварлана. Заавруудын олонлогоос програм нь тогтоно. Заавар бүр цэгтэй таслалаар (;) төгсөх ёстой. Жишээлбэл, int x; // заавар x = 23; // өөр заавар int y = x; // бас нэг заавар Зааврууд нь програмд бичигдсэн дарааллынхаа дагуу биелэгддэг: програм ажиллахдаа хамгийн эхний заавраас эхлээд сүүлийн заавар хүртэл явдаг. Гэхдээ энэ нь салаалах заавруудын тохиолдолд өөр болох юм. Хоёр төрлийн салаалах заавар байдаг: нөхцөлт салаалах болон нөхцөлгүйээр салаалах. Програмын биелэх дараалал нь мөн давтах заавруудаар өөрчлөгдөж болно. Эдгээр нь for, while, do, in, foreach түлхүүр үгүүдээр тэмдэглэгддэг.

3.1 Нөхцөлт бус салаалах заавар

Нөхцөлт бус салаалалт нь хоёр замаар хийгдэж болно. Эхнийх нь метод дуудалт юм. Програм ажиллаж байх үед метод дуудахад тухайн эгшинд ажиллаж байсан методын биелэлтийг зогсоогоод шинэ “дуудагдсан” метод руу салаалдаг. Тэр метод нь ажиллаж дуусаад утга буцаахад анхны методын дараагийн мөрнөөс биелэлтийг үргэлжлүүлдэг. using System; class Functions { static void Main( ) {

Console.WriteLine("In Main! Calling SomeMethod( )..."); SomeMethod( ); Console.WriteLine("Back in Main( ).");

} static void SomeMethod( ) {

Console.WriteLine("Greetings from SomeMethod!"); } } Гаралт: In Main! Calling SomeMethod( )... Greetings from SomeMethod! Back in Main( ). Хоёр дахь зам нь нөхцөлт бус салаалах түлхүүр үгүүдийг ашиглах: goto, break, continue, return, throw. Эдгээрийн тухай дараа дэлгэрүүлэн судлана.

3.2 Нөхцөлт салаалах заавар

Нөхцөлт салаалалт нь if, else, switch зэрэг түлхүүр үгүүдийн тусламжтай хийгдэнэ. Өгөгдсөн нөхцөлөөс хамааран салаалалт хийгдэнэ.

3.2.1 If..else заавар

‐17‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 18: C# hicheelin lekts

C# хичээлийн лекцүүд

if..else заавар нь нөхцөлт салаалалт хийхэд ашиглагдана. Нөхцөл гэдэг нь логик илэрхийлэл юм. Энэ илэрхийллийн утга үнэн үед if заавар доторх командууд биелэнэ. if заавар нь else зааврыг агуулж болно, энд нөхцөл худал үед биелэх командууд бичигдэнэ. if (expression) statement1 [else statement2] using System; class Values { static void Main( ) {

int valueOne = 10; int valueTwo = 20; if ( valueOne > valueTwo ) {

Console.WriteLine("ValueOne: {0} larger than ValueTwo: {1}", valueOne, valueTwo);

} else {

Console.WriteLine("ValueTwo: {0} larger than ValueOne: {1}", valueTwo,valueOne);

} } }

Зааврын блок Зааврын блок гэдэг нь { } хаалтуудаар хашигдсан заавруудын олонлог юм. Тухайлбал, if (someCondition) { statementOne; statementTwo; statementThree; } гэж бичиж болно.

3.2.2 Давхар if заавар

Нийлмэл нөхцөлүүдийг боловсруулахын тулд if зааврыг үүрлүүлж хэрэглэж болно. Жишээлбэл, using System; class Values { static void Main( ) {

int temp = 32; if (temp <= 32) {

Console.WriteLine("Warning! Ice on road!"); if (temp == 32) { Console.WriteLine("Temp exactly freezing, beware of water.");

‐18‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 19: C# hicheelin lekts

C# хичээлийн лекцүүд

} else { Console.WriteLine("Watch for black ice! Temp: {0}", temp); } }

} } Програмын нь агаарын температур 32-оос бага эсэхийг шалгаж байна. Хэрэв тийм бол "Warning! Ice on road!" гэсэн сэрэмжлүүлгийг хэвлэж байна. Дараа нь 32-той тэнцүү эсэхийг шалгаж дараагийг мэдэгдлийг хэвлэж байна. Энд if зааврыг if заавар дотор давхар хэрэглэсэн байна. Энд байгаа else заавар нь температур 32-оос эрс бага нөхцөлд биелэх юм.

Тэнцүүлэх оператор C#-д тэнцүүлэх оператор нь “==” ээр тэмдэглэгддэг. if (temp == 32) Үүнийг “=” утга олгох оператортай андуурч болохгүй.

3.2.3 switch заавар

Сэлгэх заавар нь угсраа if зааврын өөр нэг хувилбар нь юм, угсраа if заавар нь уншихад их төвөгтэй байдаг. Олон нөхцөлөөс сонголт хийх тохиолдолд сэлгэх зааврыг ашиглах нь илүү тохиромжтой юм. Сэлгэх зааврын логик нь тохирох утгыг олох, тэгээд биелүүлэх юм. switch (expression) {

case constant-expression: statement jump-statement

[default: statement] } Сэлгэх зааврын толгойд логик илэрхийлэл бичигдэнэ, case заавар бүрийн ард тогтмол утга тавихыг шаардана. Энд эх хэлбэрээрээ тогтмол, нэрлэсэн тогтмол, тоочих төрлийн тогтмолууд байж болно. Case зааврын ард талын утга тохирсон үед харгалзах зааврууд биелэнэ, тэгээд үсрэлт хийгдэх ёстой. Ерөнхийдөө, үсрэлт хийх заавар нь break юм. Эсвэл өөр заавар руу шилжих шаардлагатай бол goto зааврыг ашиглаж болно. using System; class Values { static void Main( ) {

const int Democrat = 0; const int LiberalRepublican = 1; const int Republican = 2; const int Libertarian = 3;

‐19‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 20: C# hicheelin lekts

C# хичээлийн лекцүүд

const int NewLeft = 4; const int Progressive = 5; int myChoice = Libertarian;

switch (myChoice) { case Democrat:

Console.WriteLine("You voted Democratic.\n"); break;

case LiberalRepublican: // fall through case Republican:

Console.WriteLine("You voted Republican.\n"); break;

case NewLeft: Console.Write("NewLeft is now Progressive"); goto case Progressive;

case Progressive: Console.WriteLine("You voted Progressive.\n"); break;

case Libertarian: Console.WriteLine("Libertarians are voting Republican"); goto case Republican;

default: Console.WriteLine("You did not pick a valid choice.\n"); break;

}

Console.WriteLine("Thank you for voting."); } } Энэ жишээнд улс төрийн бүлгүүдийг төлөөлсөн тогтмолууд тодорхойлсон байна. Дараа нь myChoice хувьсагчид Libertarian утгыг оноосон байна. Хэрэв myChoice нь Democrat -тай тохирч байвал харгалзах текстийг хэвлэнэ. Энэ тохиолдолд break заавраар төгссөн байгааг ажиглаарай, энэ нь switch зааврын гадна гарч дараагын зааврыг биелүүлэх юм. LiberalRepublican утгын дор харгалзах заавар байхгүй байна, тийм учраас энэ нь дараагийн заавар болох Republican руу “бууна”. Энэ нь сонгогдсон утга LiberalRepublican эсвэл Republican байх үед Republican заавар биелэнэ гэсэн үг. Өөр заавар руу шилжих шаардлагатай үед goto зааврыг ашиглаж болно. Хэрэв аль ч тохиолдол нь таарахгүй бол default-н ард бичигдсэн заавар биелэх болно. Програм дараахь үр дүнг хэвлэнэ: Libertarians are voting Republican You voted Republican. Thank you for voting. Энэ жишээнд сонголт хийгдэх утга нь бүхэл тоон тогтмол байна. C# нь мөн тэмдэгт мөр төрлийн утга дээр сонголт хийх боломж олгодог. Жишээ нь: case “Libertarian”:

‐20‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 21: C# hicheelin lekts

C# хичээлийн лекцүүд

3.3 Давтах заавар

C#-д үйлдлийг давтан гүйцэтгэхэд зориулсан for, while..do, do..while, foreach зааврууд байдаг. C# нь мөн goto, break, continue, return үсрэх заавруудыг хэрэглэх боломжтой.

3.3.1 goto заавар

Goto заавар нь бусад бүх давтах заавруудын үндэс нь юм. Гэхдээ энэ зааврыг ашиглахгүй байх хэрэгтэй, учир нь энэ нь кодыг ойлгомжгүй болгодог, ийм төрлийн програмыг “шпагетти” програм гэж хэлдэг. Ихэнхи туршлагатай програм зохиогчид goto зааврыг ашиглахаас зайлсхийдэг, гэхдээ энд яаж хэрэглэх тухай дурдая.

1. Тодорхой байрлалд хаяг (label) тодорхойлно 2. Дараа нь хаа нэг газраас энэ хаяг руу goto-ээр үсрэнэ

using System; public class Tester { public static int Main( ) {

int i = 0; repeat: // the label Console.WriteLine("i: {0}",i); i++; if (i < 10) goto repeat; // the dasterdly deed return 0;

} } Хэрэв goto заавар олон ашигласан програмын командын биелэх дарааллыг зурж үзвэл бие биен дээгүүрээ үсэрсэн, огтлолцсон шпагетти-тэй төстэй дүр зураг харагдана. Эндээс “шпагетти програм” гэсэн нэр томъёо үүссэн юм.

3.3.2 while давталт

while давталтын үндсэн санаа нь “энэ нөхцөл биелж байвал энэ ажлыг хий” гэсэн утга юм. while (expression) statement Энд илэрхийлэл нь логик илэрхийлэл байх ёстой. using System; public class Tester { public static int Main( ) {

int i = 0; while (i < 10) { Console.WriteLine("i: {0}",i); i++;

‐21‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 22: C# hicheelin lekts

C# хичээлийн лекцүүд

} return 0;

} } Энэ код нь өмнөх goto-н жишээн дэх кодтой ижил үйлдэл хийнэ. Гэхдээ програмын логик нь илүү ойлгожтой харагдаж байна. while заавар нөхцөл худал үед нэг ч удаа биелэхгүй.

3.3.3 do..while давталт

Зарим тохиолдолд “үнэн үед үүнийг гүйцэтгэ” гэсэн өгүүлбэрээ “үүнийг гүйцэтгэ, үнэн байх үед давт” гэж өөрчлөх хэрэг гарч болно. Ө.х үйлдэл эхлээд хийгдэнэ, үүний дараа шалгалт хийгдэнэ. Энэ зорилгоор do..while давталтыг ашиглаж болно. do expression while statement Жишээ нь, using System; public class Tester { public static int Main( ) {

int i = 11; do { Console.WriteLine("i: {0}",i); i++; } while (i < 10); return 0;

} } Энд i хувьсагчийн анхны утга 11 байна, тиймээс while дахь нөхцөл тохирохгүй, гэвч давталт доторхи заавар нэг удаа ажиллах юм.

3.3.4 for давталт

Өмнөх давтах заавруудаас харахад дараахь хэв загварын зааврууд олон тааралдаж байна: хувьсагчид анхны утга оноох (i = 0), нөхцөл шалгах (i < 10) , хэсэг зааврыг биелүүлэх, мөн хувьсагчийн утгыг өөрчлөх (i++). For давталт нь энэ бүх алхмуудыг нэг дор нэгтгэж өгдөг. for ([initializers]; [expression]; [iterators]) statement Жишээ нь, using System; public class Tester { public static int Main( ) {

for (int i=0; i<100; i++) { Console.Write("{0} ", i);

‐22‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 23: C# hicheelin lekts

C# хичээлийн лекцүүд

if (i%10 == 0) { Console.WriteLine("\t{0}", i);

} } return 0;

} } Энэ жишээнд 10-д үлдэгдэлгүй хуваагдах тоонуудыг хэвлэж байна. Хэвлэхдээ Console.Write методыг ашигласан байна, энэ нь WriteLine –тай адил боловч шинэ мөрөнд шилжихгүй үргэлжлүүлж хэвлэдэгээрээ ялгаатай. Энд зарласан i хувьсагч нь for давталтын хүрээн дотроо л үйлчлэх юм. Ө.х дараахь мөрийг нэмбэл хөрвүүлэгч алдаа заах болно. using System; public class Tester { public static int Main( ) {

for (int i=0;i<100;i++) { Console.Write("{0} ", i); if (i%10 == 0) {

Console.WriteLine("\t{0}", i); }

} Console.WriteLine("\n Final value of i: {0}", i); return 0;

} }

Сул зай ба Хаалт Сул зай ба хаалтыг ямар байдлаар хэрэглэх нь програм зохиогчийн дурын хэрэг боловч код уншихад хялбар байлгахыг бодох хэрэгтэй. Жишээлбэл, for (int i=0;i<100;i++) { Console.Write("{0} ",i); if (i%10==0) Console.WriteLine("\t{0}", i); } кодын нээх хаалтуудыг шинэ мөрөнд оруулж, үйлдлүүдийн хооронд сул зай аван дараахь байдлаар бичиж болно. for (int i=0; i<100; i++) { Console.Write("{0} ", i); if (i%10 == 0) { Console.WriteLine("\t{0}", i); } }

‐23‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 24: C# hicheelin lekts

C# хичээлийн лекцүүд

Энэ нь илүү уншихад ойлгомжтой бичиглэл юм.

3.3.5 foreach давталт

Энэ давталт нь C төрлийн програм зохиогчдын хувьд шинэ зүйл юм, гэхдээ Visual Basic програм зохиогчдын хувьд танил байх. Энэ давталт нь массив болон бусад өгөгдлийн бүтцийн бүх элементүүдээр давталт хийхэд хэрэглэгддэг. foreach (type identifier in expression) statement Жишээ: using System; public class Tester { static void Main() {

int[] intArray; intArray = new int[5]; // populate the array for (int i = 0;i<intArray.Length;i++) { intArray[i] = i; } foreach (int i in intArray) { Console.WriteLine(i.ToString()); }

} }

3.3.6 continue ба break зааврууд

Зарим тохиололд давталт доторх үлдсэн хэсгийг билүүлэлгүйгээр давталтыг шинэчлэн эхлүүлэх шаардлага гардаг. continue заавар нь давталтын удирдлагыг дахин эхэнд нь аваачиж биелүүлэхэд хэрэглэгддэг. Мөн давталтыг таслан зогсоох боломжтой, үүнд break зааврыг ашиглаж болно. break ба continue зааврууд нь кодыг олон гарцтай болгож унших болон засахад төвөгтэй болгодог. Тиймээс бодолтой хэрэглэх хэрэгтэй. Доорхи жишээ нь урсгалын дохио хянах програм юм. Дохиог гарнаас Console.ReadLine методын тусламжтай оруулна. Алгоритм нь энгийн: “0” дохио хүлээж авбал нөхцөл хэвийн байна гэсэн үг, арга хэмжээ авах шаардлагагүй. Таслах дохио “A” хүлээн авсан үед боловсруулалт шууд зогсоно. Бусад дохио авсан үед анхааруулга гарч арга хэмжээ авахыг мэдэгдэнэ. “X” дохио хүлээн авсан үед анхааруулга хийж бөгөөд давталт зогсоно. using System; public class Tester { public static int Main( ) {

‐24‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 25: C# hicheelin lekts

C# хичээлийн лекцүүд

string signal = "0"; // initialize to neutral while (signal != "X") { // X indicates stop Console.Write("Enter a signal: "); signal = Console.ReadLine( ); // do some work here, no matter what signal you receive Console.WriteLine("Received: {0}", signal); if (signal == "A") {

// faulty - abort signal processing // Log the problem and abort. Console.WriteLine("Fault! Abort\n"); break;

}

if (signal == "0") { // normal traffic condition // log and continue on Console.WriteLine("All is well.\n"); continue;

} // Problem. Take action and then log the problem and then continue on Console.WriteLine("{0} -- raise alarm!\n",signal);

} return 0; } }

Нэр тодорхойлох

#define DEBUG заавар нь DEBUG нэртэй препроцессорт зориулсан тогтмол утга үүсгэнэ. Мөн ийм зааврууд нь өөр кодноос using заавраар дагаж орж ирж болно. #define DEBUG //... ердийн код – препроцессорт хамааралгүй #if DEBUG // туршилт хийх үед хөрвүүлэгдэх, ажиллах код #else // туршилт хийгээгүй үед ажиллах код #endif //... ердийн код – препроцессорт хамааралгүй Препроцессор ажиллах үед #define зааврын дагуу DEBUG нэрийг үүсгэнэ. Дараа нь хэсэг ердийн кодыг алгасана, дараа нь #if-#else-#endif блоктой таарна. #if заавар нь DEBUG нэртэй тогтмол зарлагдсан эсэхийг шалгаж байна, ийм нэр өмнө үүссэн учраас #if ба #else –н хооронд бичигдсэн код програм руу хөрвүүлэгдэнэ. Харин #else ба #endif-н хоорондох код хөрвүүлэгдэхгүй. Ө.х энэ хоорондох код нь эцсийн ассемблай файл дотор үүсэхгүй гэсэн үг. #if ба #endif-н хооронд бичигдээгүй бусад кодын хувьд препроцессорт хамаагүй бөгөөд програм руу хөрвүүлэгдэх болно.

‐25‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 26: C# hicheelin lekts

C# хичээлийн лекцүүд

Үүсгэсэн нэрийг #undefine заавраар хасаж болно. Жишээ нь: #define DEBUG #if DEBUG // энэ код хөвүүлэгдэнэ #endif #undef DEBUG #if DEBUG // энэ код хөрвүүлэгдэхгүй #endif Эхний #if биелэгдэнэ, дараагийнх нь биелэгдэхгүй. (DEBUG нэр байхгүй болсон)

#if, #elif, #else, #endif

Препроцессорт олон сонголтоос сонгох заавар байхгүй, гэхдээ #elif, #else заавруудаар орлуулж болно. #elif заавар нь else-if гэсэн логиктой юм. #if DEBUG // compile this code if debug is defined #elif TEST // compile this code if debug is not defined // but TEST is defined #else // compile this code if neither DEBUG nor TEST // is defined #endif

#region

#region заавар нь тайлбар бүхий текст мужийг тодорхойлдог. Энэ зааврар нь Visual Studio гэх мэт хэрэгсэл ашиглах үед програмын кодын зарим хэсгийг эвхэж зөвхөн тайлбарыг нь харуулахад хэрэглэгддэг. Жишээлбэл, доорх жишээнд ийм кодын муж тодорхойлсон ба муж нь дэлгэгдсэн харагаж байна.

‐26‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 27: C# hicheelin lekts

C# хичээлийн лекцүүд

Энд муж нь #region ба #endregion зааврын хооронд бичигдсэн байна. Энэ мужийг эвхсэн үед зөвхөн тайлбар нь харагдана.

        

‐27‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 28: C# hicheelin lekts

C# хичээлийн лекцүүд

Лекц №4.5.6 Сэдэв: Класс ба Объектууд

Дэд сэдвүүд:

• Класс тодорхойлох • Объект үүсгэх • Статик гишүүд • Объектыг устгах • Параметер дамжуулах • Метод болон байгуулагчыг дахин тодорхойлох • Операторыг дахин тодорхойлох • Өгөгдлийг далдлах – Проперти

Бид int, long, char гэх мэт үндсэн төрлүүдийг мэднэ. Програмчлалын хэл нь програм зохиогчид шинэ, илүү нийлмэл төрлүүдийг үүсгэх боломжийг олгох ёстой. C#-д класс үүсгэж шинэ төрлүүдийг бий болгож болно. Классын төлийг объект гэж хэлдэг. Програм ажиллаж байх үед объект нь санах ойд үүсдэг. Класс ба Объектын хоорондох ялгаа бол нохойны тухай дүрслэл, төсөөлөл ба жинхэнэ таны өмнө сууж байгаа нохой хоёрын хоорондох ялгаатай болон ижил зүйл юм. Та нохойны дүрслэлтэй тоглож чадахгүй, зөвхөн бодит нохойтой л чадна. Dog класс нь “нохой ямар байдаг вэ” гэдгийг тодорхойлно: жин, өндөр, нүдний өнгө, үсний өнгө гэх мэт. Тэд мөн идэх, явах, хуцах, унтах гэх мэт хийж чаддаг авируудтай. Тодорхой нэг нохой, жишээ нь миний нохой, тодорхой жин (62 pounds), өндөр (22 inches), нүдний өнгө (black), үсний өнгөтэй (yellow). Тэр мөн нохойнуудын хийж чаддаг бүх л зүйлийг хийж чадна.

‐28‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 29: C# hicheelin lekts

C# хичээлийн лекцүүд

Объект хандлагат прорамчлалын том давуу тал нь програмын элементүүдийн боломж, шинжүүдийг нэгэн дан, биеэ даасан нэгжид далдлан кодлох боломж олгодогт оршдог. Өгөгдлийн далдлалт, удамшил, полиморфизм нь объект хандлагат програмчлалын гурван тулгуур ухагдахуун юм. / Хуучны програм зохиогчид нэгэн хошин асуултыг тавьдаг. Объект хандлагат програм зохиогчийн хувьд гэрлийг унтраахад хэдэн үйлдэл хэрэгтэй вэ? Хариулт нь: нэг ч үйлдэл хийхгүй, зүгээр гэрлийн лампад өөрийгөө унтраа гэж хэлэхэд хангалттай. /

3.1 Класс тодорхойлох

Классыг class түлхүүр үгээр тодорхойлно. Бичиглэл нь дараахь байдалтай: [attributes] [access-modifiers] class identifier [:base-class ] {

class-body } Аттрибут болон хандалт тодорхойлогчийн (access-modifiers) тухай дараагийн лекцээр үзнэ. Identifier нь классын нэр юм. base-class-ийн тухай мөн удамшлын үед ярина. Классын биеийг муруй хаалтаар {} хашиж бичнэ. C#-д бүх зүйл класс дотор бичигддэг. public class Tester {

public static int Main( ) { //... }

} Класс үүсгэх үед түүний бүх шинжүүд, авируудыг тодорхойлох ёстой. Дараахь цаг хадгалах, хэвлэх жишээнд анхаарал хандуулая. Классын дотоод төлөв нь одоогийн он, сар, өдөр, цаг, минут, секундыг дүрслэх чадвартай байх ёстой. Мөн энэ класс нь цагыг хэвлэн харуулах чадвартай байх хэрэгтэй. Ийм классыг 6 хувьсагч, 1 методтойгоор тодорхойлоё.

‐29‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 30: C# hicheelin lekts

C# хичээлийн лекцүүд

using System; public class Time { // public methods public void DisplayCurrentTime( ) {

Console.WriteLine("stub for DisplayCurrentTime"); } // private variables int Year; int Month; int Date; int Hour; int Minute; int Second; } public class Tester { static void Main( ) {

Time t = new Time( ); t.DisplayCurrentTime( );

} } Энэ жишээнд Main() метод дотор Time классын объектыг үүсгэж t хувьсагчид оноосон байна. t нь Time классын объект учраас DisplayCurrentTime( ) методыг ашиглаж болно гэсэн үг. t.DisplayCurrentTime( );

3.1.1 Хандалт тодорхойлох

Хандалт тодорхойлох гэдэг нь тухайн классын гишүүн хувьсагч, методууд руу ямар методууд хандаж болох вэ гэдгийг тодорхойлохыг хэлнэ. Хандалт Хязгаарлалт public Хязгаарлалт байхгүй. Public гэж тэмдэглэгдсэн гишүүд рүү ямар ч метод, ямар ч

классаас хандаж болно. private Private гэж тэмдэглэгдсэн гишүүд рүү зөвхөн тухайн классын методууд хандана protected Protected гэж тэмдэглэгдсэн гишүүд рүү тухайн классын методууд ба түүнээс

удамшсан классын методууд хандана internal Internal гэж тэмдэглэгдсэн гишүүд рүү тухайн классыг агуулж байгаа ассемблай

доторх бүх классуудаас хандах боломжтой protected internal Ассемблай доторх бүх классуудаас хандахаас гадна тухайн классаас удамшсан

классын методууд хандана. Ерөнхийдөө классын гишүүд нь private хандалттай байдаг. Гишүүний хандалтыг нь заагаагүй бол private гэж ойлгоно. Тиймээс өмнөх жишээн дэх Time классын гишүүд нь private хандалттай гэсэн үг. private int Year; private int Month; private int Date; private int Hour; private int Minute;

‐30‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 31: C# hicheelin lekts

C# хичээлийн лекцүүд

private int Second;

3.1.2 Методын аргумент

Метод нь дурын тооны параметерийг хүлээн авдаг байж болно. Методын нэрний араас параметүүдийг хаалтад жагсаан бичнэ. Жишээлбэл, “аргумент” ба “параметер” гэсэн ойлголтуудыг ихэнх тохиолдолд адилхан хэрэглэдэг, гэхдээ аргументыг тодорхойлдог, параметерыг метод дуудах үед дамжуулдаг гэсэн ялгааг нь ойлгох хэрэгтэй. void MyMethod (int firstParam, button secondParam) {

// ... } MyMethod метод нь int, button төрлийн 2 параметер хүлээж аваад void утга буцааж байна.

3.2 Объект үүсгэх

Объектыг new түлхүүр үгээр санах ойд үүсгэдэг. Time t = new Time(); Объект нь заалт төрөл юм, ө.х t нь Time объектыг яг агуулахгүй, харин санах ойд нэргүй Time төрлийн объект үүсэх ба тэр объект руу хүрэх хаягыг t агуулна. Зураг?

3.2.1 Байгуулагч

Дараахь Time объектыг үүсгэж байгаа бичиглэл нь метод дуудах бичиглэлтэй төстэй харагдаж байна. Time t = new Time(); Үнэндээ, объектыг үүсгэх үед метод дуудагддаг юм. Энэ дуудагдах методыг нь байгуулагч гэж нэрлэдэг. Байгуулагчыг нь класс дотор тодорхойлж өгөх ёстой, эсвэл CLR үүнийг орлуулж хийж өгдөг. Байгуулагчын үүрэг бол классаар заагдсан объектыг үүсгэх, түүнийгээ зөв төлөвт оруулах юм. Байгуулагч ажиллахын өмнө объект нь тодорхой бус санах ойн муж байдаг, байгуулагч ажилласны дараа зөв болж санах ойн муж эзэлдэг. Байгуулагчийг тодорхойлохдоо классын нэртэй ижил медотыг тодорхойлдог. Байгуулагч нь буцаах утгагүй байдаг ба ихэнхдээ public хандалттай байдаг. Хэрэв аргумент авах шаардлагатай бол аргументуудыг зааж өгөх ёстой. Time класс нь байгуулагч тодорхойлогдоогүй байна. Хэрэв байгуулагч байхгүй бол хөрвүүлэгч default байгуулагчийг санал болгох ба энэ нь объектыг санах ойд үүсгэнэ,

‐31‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 32: C# hicheelin lekts

C# хичээлийн лекцүүд

гэхдээ өөр ямар нэг үйлдэл хийхгүй. Гишүүн хувьсагчдад нь тогтсон (default) утгууд оноогдоно. Жишээлбэл үндсэн төрлүүдийн хувьд дараахь байдалтай: Төрөл Тогтсон утга numeric (int, long г.м) 0 bool false char ‘\0’ (null) enum 0 reference null Time класст DateTime төрлийн нэг параметер хүлээн авах байгуулагч нэмж бичие. public class Time { // public accessor methods public void DisplayCurrentTime( ) {

System.Console.WriteLine("{0}/{1}/{2} {3}:{4}:{5}", Month, Date, Year, Hour, Minute, Second);

} // constructor public Time(System.DateTime dt) {

Year = dt.Year; Month = dt.Month; Date = dt.Day; Hour = dt.Hour; Minute = dt.Minute; Second = dt.Second;

} // private member variables int Year; int Month; int Date; int Hour; int Minute; int Second; } public class Tester { static void Main( ) {

System.DateTime currentTime = System.DateTime.Now; Time t = new Time(currentTime); t.DisplayCurrentTime( );

} } Энэ жишээнд байгуулагч нь DateTime төрлийн параметер хүлээж аваад Time объектын харгалзах гишүүн хувьсагчдад оноож байна. DateTime нь System санд байдаг класс юм. DateTime классын Now статик гишүүн метод нь системийн одоогийн цагыг өгдөг.

3.2.2 Хуулагч байгуулагч

Хуулагч байгуулагч нь байгаа объектоос өөр нэг ижил төрлийн шинэ объектийг үүсгэдэг. Ийм байгуулагч нь объектыг хувилахад хэрэглэгдэх юм. Жишээлбэл, Time байгуулагчид Time төрлийн параметер дамжуулж тухайн объектын утгуудтай ижил утгуудыг агуулах шинэ объект үүсгэх хэрэгтэй болсон гэж үзэе. C#-д хуулагч байгуулагч байхгүй, тиймээс үүнийг өөрөө хийх хэрэгтэй. Тухайлбал дараахь байгуулагчийг үүсгэж болно.

‐32‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 33: C# hicheelin lekts

C# хичээлийн лекцүүд

public Time(Time existingTimeObject) {

Year = existingTimeObject.Year; Month = existingTimeObject.Month; Date = existingTimeObject.Date; Hour = existingTimeObject.Hour; Minute = existingTimeObject.Minute; Second = existingTimeObject.Second;

} Time t3 = new Time(t2);

Хувилах .NET-н зарим класс Clone() методыг өөртөө агуулсан байдаг. Энэ метод нь тухайн объектын яг ижил хуулбарыг санах ойд үүсгэдэг.

3.2.3 this түлхүүр үг

this түлхүүр үг нь тухайн объектыг өөрийг нь заана. this заалт нь классын статик биш гишүүд рүү хандах “нууц” заалт юм. Ихэнхдээ this заалтыг хэрэглэх гурван хэрэглээ байдаг. Нэгдүгээрт, гишүүн өгөгдлийг параметерээс ялгах. public void SomeMethod (int hour) {

this.hour = hour; } Энэ жишээнд SomeMethod() метод нь гишүүн хувьсагчийн нэртэй ижил hour нэртэй параметерийг авч байна. Энэ үед this заалт нь нэрсийг ялгахад туслана, this.hour нь гишүүн хувьсагчийг илэрхийлж байна, hour нь параметерийг хэлж байна. Хоёрдугаарт, тухайн объектыг өөрийг нь өөр методод параметер болгон дамжуулж өгөхөд ашиглана. public void FirstMethod(OtherClass otherObject) {

otherObject.SecondMethod(this); } Гуравдугаарт, индекслэгчид ашиглана.

3.3 Статик гишүүд

Классын гишүүн нь статик байж болно. Статик бус гишүүдийн хувьд тухайн классаас үүссэн объекттой холбогдсон байдаг бол харин статик гишүүдийн хувьд холбоогүй байдаг. Статик гишүүдэд түүнийг агуулж байгаа классын нэрээр дамжуулан хандаж болно. Жишээлбэл, Button нэртэй класс SomeMethod нэртэй статик гишүүн методтой бол

‐33‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 34: C# hicheelin lekts

C# хичээлийн лекцүүд

Button.SomeMethod() гэж дуудна. Харин энэ классаас үүссэн btnUpdate гэсэн объект байх тохиолдолд btnUpdate.SomeMethod() гэж болохгүй. Энэ тохиолдолд хөрвүүлэгч алдаа заах болно. Статик гишүүд нь глобаль методтой адил гэж ойлгож болно, тиймээс объект үүсгэлгүйгээр дуудаж хэрэглэж болно. Класс дотор статик гишүүн хэрэглэхийн давуу тал нь тухайн гишүүн классаараа хаяглагдана, энэ нь томоохон програм хангамж хөгжүүлэхэд нэрний хувьд илүү оновчтой болгож тусладаг. Програмд ашиглагдаж байгаа бүх статик методуудыг нэг класс дотор оруулж болох юм. Гэвч энэ нь объект хандлагат загварчлалын битүүмжлэх чанарыг алдагдуулсан зүйл болох юм.

3.3.1 Статик байгуулагч

Статик байгуулагч нь ердийн байгуулагчтай төстэй, гэхдээ тухайн классын объект үүсэхээс өмнө дуудагддаг. Ерөнхийдөө классын статик гишүүдтэй ажиллахад хэрэглэгддэг. Статик байгуулагч нь далд хэлбэрийн public хандалттай бөгөөд ханалт хувиргагч байхгүй. Статик байгуулагч нь static түлхүүр үгээр тодорхойлогдоно. class Player { static Player() { _counter = -1; } public Player(string Name) { } }

Статик байгуулагч яг хэзээ дуудагдахыг мэдэх боломжгүй. Гэхдээ дараахь байдлаар явагдана гэдэг нь тодорхой:

• Статик байгуулагч нь классын хамгийн эхний объект үүсэхээс өмнө дуудагдана. • Статик байгуулагч нь зөвхөн нэг удаа дуудагдана. • Статик байгуулагч нь статик гишүүд анхны утгаа авсны дараа дуудагдана. • Статик байгуулагч нь статик гишүүдэд хандахаас өмнө дуудагдана.

Статик байгуулагч нь програм эхлэхэд нэг удаа бэлдэх шаардлагатай бэлтгэл ажлуудыг хийхэд тохиромжтой.

3.3.2 private байгуулагч

C#-д глобаль хувьсагч, функц гэсэн ойлголт байхгүй. Тиймээс статик гишүүдийг агуулсан жижиг туслах класс үүсгэх хэрэгтэй болно. Энэ нь сайн дизайн ч бай, муу дизайн ч бай хэрэв тийм класс үүсгэж байгаа бол тэр классаас ямар ч объект үүсгэхийг

‐34‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 35: C# hicheelin lekts

C# хичээлийн лекцүүд

зөвшөөрөхгүй байх хэрэгтэй. Үүнийг private хандалтаар хийж болно. Ингэснээр классаас объект үүсгэх боломжгүй болно.

3.3.3 Статик гишүүн өгөгдөлийн хэрэглээ

Статик гишүүн өгөгдөлийн нэг нийтлэг хэрэглээ бол тухайн классаас үүсэж байгаа объектуудыг тоолох юм. Дараахь жишээнд instances нэртэй статик гишүүн өгөгдлийг Cat класс дотор зарлаж энэ хувьсагчийн эхний утгыг 0-ээр оноож байна. Энэ тоолуур нь объект шинээр үүсэх бүрд нэгээр нэмэгдэж байна. using System; public class Cat { public Cat( ) {

instances++; } public static void HowManyCats( ) {

Console.WriteLine("{0} cats adopted",instances); } private static int instances = 0; } public class Tester { static void Main( ) {

Cat.HowManyCats( ); Cat frisky = new Cat( ); Cat.HowManyCats( ); Cat whiskers = new Cat( ); Cat.HowManyCats( );

} } Гаралт: 0 cats adopted 1 cats adopted 2 cats adopted Гишүүн өгөгдлийг public хандалттай байлгах нь тохиромжгүй юм. Энэ нь мөн статик гишүүн өгөгдлийн хувьд ч хамаатай. Тиймээс статик гишүүнийг мөн private хандалттай тодорхойлох хэрэгтэй. Дээрх жишээнд instances статик гишүүн хувьсагчийг private хандалттай зарлаж, public хандалттай HowManyCats() статик гишүүн методыг тодорхойлсон байна. HowManyCats() нь мөн статик учраас instances статик гишүүн рүү хандаж байна.

3.4 Объектыг устгах

C# нь санах ойн цэвэрлэгчтэй учраас объектуудыг хэрэглэж дууссаны дараа устгах ажлыг заавал хийх шаардлагагүй. Хэдий тийм боловч хяналтгүй нөөц10 програмдаа ашиглаж байгаа бол ашиглаж дууссаны дараа ил хэлбэрээр устгах шаардлагатай. Үүнд

                                                 10 unmanaged resource 

‐35‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 36: C# hicheelin lekts

C# хичээлийн лекцүүд

зориулж Finalize() нэртэй метод хэрэглэгддэг, энэ метод нь объект устах үед үлдэгдэл цэвэрлэгчээр дуудагддаг.

11Хэрэв зөвхөн хяналттай нөөцүүд ашиглаж байгаа бол энэ методыг класс дотроо хэрэглэх шаардлагагүй. Мөн Finalize() методыг шууд дуудах хэрэггүй. Үлдэгдэл цуглуулагч үүнийг хийх болно.

Цэвэрлэлт яаж хийгддэг вэ Үлдэгдэл цэвэрлэгч нь Finalize() методтой бүх объектын жагсаалтыг гаргана. Энэ жагсаалт нь объект үүсэх, устах бүрд шинэчлэгдэж байдаг. Энэ жагсаалтад байгаа объект нь цэвэрлэгдэх объектын дараалалд эхэлж бичигддэг. Finalize() метод ажилласны дараа үлдэгдэл цэвэрлэгч объектыг устгана, дараа нь утсгалын дарааллаа шинэчлэнэ, мөн Finalize() хийгдэх объектын жагсаалтаа цэвэрлэнэ.

3.4.1 Устгагч

C#-д устгагч методыг дараахь байдлаар тодорхойлно. ~MyClass( ) { } Устгагч метод нь зүгээр л Finalize() методыг дуудах өөр нэг хэлбэр юм. Ө.х ~MyClass( ) {

// do work here } гэж бичих нь MyClass.Finalize( ) {

// do work here base.Finalize( );

} бичиглэлтэй адилхан юм. Ер нь эндүүрэл үүсгэхгүйн тулд устгагч методыг ашиглахгүй байх нь зүйтэй, шаардлагатай бол Finalize() методыг ашиглах хэрэгтэй.

3.4.2 Finalize ба Dispose

Finalize() метод нь үлдэгдэл цэвэрлэгчээр дуудагдах учраас түүнийг код дотор дуудах нь хориотой. Зарим тохиолдолд үлдэгдэл цэвэрлэгчид орхилгүйгээр тэр дариуд нь санах ойгоос цэвэрлэх хэрэг гарна. Хэрэв хяналтгүй нөөц ашиглаад түүнийгээ тэр дариуд нь устгах шаардлагатай бол IDisposable интерфэйсийг классдаа хэрэгжүүлэх хэрэгтэй. Энэ интерфэйс нь Dispose() нэртэй методыг өөртөө агуулна. Dispose() методын утга нь “Finalize() дуудагдахыг хүлээхгүй, шууд устга” юм.                                                  11 managed resource 

‐36‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 37: C# hicheelin lekts

C# хичээлийн лекцүүд

3.4.3 Close методыг хэрэглэх

Зарим объектыг устгахад Close() методыг дуудах нь тохиромжтой байдаг. Тухайлбал, урсгал, файлтай ажиллах объектууд байна. private хандалттай Dispose() метод, public хандалттай Close() метод тодорхойлоод, Close() нь Dispose()-г дууддаг байдлаар зохион байгуулж болно.

3.4.4 using заавар

Цэвэрлэгч хэзээ ажиллахыг хянаж чадахгүй. Dispose() хэзээ дуудагдах нь тодорхой бус гэсэн үг. Гэхдээ C#-д using зааврыг ашиглан тухайн объектын амьдрах мужийг тодорхой зааж, хэзээ устахыг нь хэлж өгч болно. Объектын амьдрах муж нь нээх хаалтаар эхлээд хаах хаалт таарах үед автоматаар Dispose() метод дуудагдаж дуусах юм. using System.Drawing; class Tester { public static void Main( ) {

using (Font theFont = new Font("Arial", 10.0f)) { // use theFont } // compiler will call Dispose on theFont

Font anotherFont = new Font("Courier",12.0f); using (anotherFont) { // use anotherFont } // compiler calls Dispose on anotherFont

} } Жишээний эхний хэсэгт Font объект using заавартай хамт үүсэж байна, заавар дуусахад Dispose() дуудагдах болно. Хоёр дахь хэсэгт Font объект using зааврын гадна үүсгэгдэж байна. Тэрхүү Font объектыг ашиглах болмогц using заавар дотор оруулна, заавар дуусахад мөн Dispose() дуудагдах болно. using заавар нь мөн тооцоолоогүй алдаануудаас хамгаалдаг. Ө.х using заавар яаж ажиллаж дууссанаас үл хамааран объектыг төгсгөлд нь заавал устгадаг. Энэ нь try-catch-finally блоктой ижил гэсэн үг. Энэ блокын тухай алдаа барих заавруудыг судлах үед ярина.

3.5 Параметер дамжуулах

Үндсэн төрлүүд нь методод утгаараа дамжигдана. Метод руу үндсэн төрлийн объект дамжуулах үед тухайн методод зориулсан түр зуурын хуулбар үүсдэг гэсэн үг. Метод дууссаны дараа тэрхүү хуулбар нь хаягдана. Ихэнхдээ ингэж утгаар дамжуулалт хийгддэг. Зарим үед заалтаар дамжуулах хэрэг гардаг. Заалтаар объектыг дамжуулахад ref параметер хувиргагчыг хэрэглэнэ, ref-г анхны утга олголгүйгээр дамжуулах

‐37‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 38: C# hicheelin lekts

C# хичээлийн лекцүүд

параметер дээр хэрэглэх бол out параметер хувиргагчыг хэрэглэнэ. Мөн хувьсах тооны параметер дамжуулах үед params параметер хувиргагчыг ашигладаг.

3.5.1 Заалтаар дамжуулах

Метод нь нэг л объектыг буцаадаг. Time класс дээр жишээ авая, GetTime() нэртэй цаг, минут, секунд буцаадаг метод нэмэх хэрэгтэй байг. Энэ тохиолдолд метод нь 3 утга буцааж чадахгүй, тиймээс 3 параметер дамжуулаад тэр 3 параметерээрээ хүссэн утгуудаа буцаан авч болно. Энэ тохиололд методыг дараахь байдлаар тодорхойлох хэрэгтэй болно. public void GetTime(ref int h, ref int m, ref int s) {

h = Hour; m = Minute; s = Second;

} Методын дуудалт дээр мөн өөрчлөлт хийх хэрэгтэй. t.GetTime(ref theHour, ref theMinute, ref theSecond); Хэрэв дамжуулахдаа ref түлхүүр үгийг орхивол хөрвүүлэгч int төрлөөс ref int төрөл рүү хөрвүүлж чадахгүй гэсэн алдаа хэлэх болно. Объектыг заалтаар дамжуулах үед түүний хуулбар дамжуулагдахгүй, харин тухайн объектыг заах заалт дамжуулагдана. Ингэснээр метод тухайн объект дээр ажиллана гэсэн үг, хуулбар дээр биш. Энгийн үгээр хэлбэл заалтаар дамжуулна гэдэг нь “энэ объект байна, үүн дээр ажилла”, утгаар дамжуулна гэдэг нь “энэ яг адилхан хуулбар нь байна, үүн дээр ажилла” гэсэн үг юм.

3.5.2 out параметер

C# нь хувьсагчидыг ашиглахын өмнө утга оноосон байхыг шаарддаг. Жишээлбэл, theHour, theMinute, theSecond хувьсагчдыг GetTime() метод руу дамжуулахын өмнө утга оноохгүй бол хөрвүүлэгч алдаа хэлнэ. Тиймээс тэдгээрт 0 анхны утгуудыг оноож өгч болно. int theHour = 0; int theMinute = 0; int theSecond = 0; t.GetTime( ref theHour, ref theMinute, ref theSecond); Гэвч энэ нь тухайн параметерээр дамжуулан зөвхөн буцах утга авах тохиолдолд илүү зүйл юм шиг харагдаж байна, гэвч ингэхгүй бол алдаа заана. Use of unassigned local variable 'theHour' Use of unassigned local variable 'theMinute' Use of unassigned local variable 'theSecond'

‐38‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 39: C# hicheelin lekts

C# хичээлийн лекцүүд

Энэ нөхцөлд out параметер хувиргагчыг ашиглах нь тохиромжтой. out нь параметер заавал эхний утга оноогдсон байх ёстой гэсэн шаардлагыг байхгүй болгоно. GetTime() методын зарлалтыг дараахь байдлаар засна. public void GetTime(out int h, out int m, out int s) {

h = Hour; m = Minute; s = Second;

} Дуудалт нь дараахь байдалтай. t.GetTime( out theHour, out theMinute, out theSecond);

3.6 Метод болон байгуулагчыг дахин тодорхойлох

Олон тохиолдолд ижил нэртэй нэгээс олон функцтэй байх хэрэг гардаг. Хамгийн энгийн жишээ бол байгуулагч метод. Жишээлбэл, Time класс нь ганц DateTime төрлийн параметер авах байгуулагчтай байна. Time объектыг өөрөөр жил, сар, өдөр, цаг, минут, секунд параметерүүдээр байгуулах байгуулагч хэрэгтэй байж болно. Энэ тохиолдолд метод дахин тодорхойлолт хийгдэнэ. Методын таних тэмдэг нь (signature) түүний нэр, параметерийн жагсаалтаар тодорхойлогддог. Ялгаатай нэртэй эсвэл ялгаатай параметртэй методуудыг ялгаатай таних тэмдэгтэй байна гэж хэлнэ. void myMethod(int p1); void myMethod(int p1, int p2); void myMethod(int p1, string s1); Дээрх жишээнд бүгд ижил нэртэй метод боловч хоёр дахь метод нь эхнийхээс параметерийн тоогоороо ялгаатай байна, хоёр дахь нь гурав дахиас параметерийн төрлөөрөө ялгаатай байна. Өмнөх жишээн дэх Time классд шинэ байгуулагч нэмэе. public class Time { // public accessor methods public void DisplayCurrentTime( ) {

System.Console.WriteLine("{0}/{1}/{2} {3}:{4}:{5}", Month, Date, Year, Hour, Minute, Second);

} // constructors public Time(System.DateTime dt) {

Year = dt.Year; Month = dt.Month; Date = dt.Day; Hour = dt.Hour; Minute = dt.Minute; Second = dt.Second;

} public Time(int Year, int Month, int Date,

‐39‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 40: C# hicheelin lekts

C# хичээлийн лекцүүд

int Hour, int Minute, int Second) { this.Year = Year; this.Month = Month; this.Date = Date; this.Hour = Hour; this.Minute = Minute; this.Second = Second;

} // private member variables private int Year; private int Month; private int Date; private int Hour; private int Minute; private int Second; } public class Tester { static void Main( ) {

System.DateTime currentTime = System.DateTime.Now; Time t = new Time(currentTime); t.DisplayCurrentTime( ); Time t2 = new Time(2000,11,18,11,03,30); t2.DisplayCurrentTime( );

} } Ингээд Time класс нь 2 байгуулагчтай болж байна. Хөрвүүлэгч t1 объектыг байгуулах үед эхний байгуулагчыг дуудна, t2 объектыг байгуулах үед хоёр дахь байгуулагч методыг дуудна гэдгийг мэдэх болно. Хүлээн авах параметерийн тоогоороо ялгаатай байгаа учраас.

3.7 Операторыг дахин тодорхойлох

Өгөгдсөн төрлийн хувьд операторуудыг хэрхэн дахин тодорхойлохыг бэйсболын цохилтын дундаж үзүүлэлтийг загварчилсан жишээн дээр үзэе. Бэйсболд цохилтын үзүүлэлт гэдэг нь нэг тоглогчийн амжилттай цохилтын тоог нийт цохисон тоонд хуваасан утгыг илэрхийлнэ.

Дараахь код нь BattingAverage төрлийн эхний хувилбар юм.

using System; namespace MSPress.CSharpCoreRef.BattingAverageExample { public struct BattingAverage { // Constructs a new BattingAverage value type instance public BattingAverage(int atBats, int hits) { TestValid(atBats, hits); _atBats = atBats; _hits = hits; }

‐40‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 41: C# hicheelin lekts

C# хичээлийн лекцүүд

/// Returns the batting average, subject to floating- /// point rounding public float Average() { if(_atBats == 0) return 0.0f; else return (float)_hits / (float)_atBats; } /// Tests for valid hits and at bats, throwing an exception /// if the parameters are invalid private static void TestValid(int testAtBats, int testHits){ if(testAtBats < 0) { string msg = "At bats must not be negative"; throw new ArgumentOutOfRangeException(msg); } if(testAtBats < testHits) { string msg = "Hits must not exceed at bats"; throw new ArgumentOutOfRangeException(msg); } } public int _atBats; public int _hits; } }

BattingAverage бүтэц нь нийт цохилтын тоо, амжилттай цохилтын тоог илэрхийлэх далд гишүүн өгөгдлүүдтэй. Методууд нь цохилтын үзүүлэлтийг шалгах, тооцоолоход хэрэглэгдэнэ.

Ингээд BattingAverage бүтэц нь цохилтын үзүүлэлтийг хадгалах, тооцоолоход ашиглагдаж болохоор боллоо. Хэдийгээр эхний хувилбар гарсан боловч объектуудыг харьцуулах зэрэг үйлдэл хийхэд болхи зохиомжтой болсон байна:

if (firstBatter.Average() < secondBatter.Average()) { // secondBatter's average is higher... }

BattingAverage классын Average методыг дуудаж үр дүнг нь харьцуулахын оронд харьцуулах операторыг энэ төрөл дээр дахин тодорхойлж ердийн үндсэн төрлүүд дээрх шиг ашиглах нь тохиромжтой байна:

if (firstBatter < secondBatter) { // secondBatter's average is higher... }

Дараагийн хувилбарт бүх шаардлагатай үйдлүүдийг дахин тодорхойлоё.

// Equality operator for batting averages public static bool operator ==(BattingAverage left, BattingAverage right) { if((object)left == null) return false; else

‐41‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 42: C# hicheelin lekts

C# хичээлийн лекцүүд

return left.Equals(right); } // Inequality operator for batting averages public static bool operator !=(BattingAverage left, BattingAverage right) { return !(left == right); } // Override of the Object.Equals method; returns // true if the current object is equal to another // object passed as a parameter public override bool Equals(object other) { bool result = false; if(other != null) { if((object)this == other) { result = true; } else if(other is BattingAverage) { BattingAverage otherAvg = (BattingAverage)other; result = Average() == otherAvg.Average(); } } return result; } // Converts the batting average to a string, and then // uses the string to generate the hash code public override int GetHashCode() { return ToString().GetHashCode(); } // Compares two operands using the greater than operator public static bool operator >(BattingAverage left, BattingAverage right) { return left.Average() > right.Average(); } // Compares two operands using the less than or equal to operator public static bool operator <=(BattingAverage left, BattingAverage right) { return left.Average() <= right.Average(); } // Compares two operands using the less than operator public static bool operator <(BattingAverage left, BattingAverage right) { return left.Average() < right.Average(); } // Compares two operands using the greater than or equal to operator public static bool operator >=(BattingAverage left, BattingAverage right) { return left.Average() >= right.Average(); } // Returns true if the object is logically false

‐42‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 43: C# hicheelin lekts

C# хичээлийн лекцүүд

public static bool operator false(BattingAverage avg) { return avg.Average() == 0; } // Returns true if the object is logically true public static bool operator true(BattingAverage avg) { return avg.Average() != 0; } // Performs an AND operation on two batting averages public static BattingAverage operator &(BattingAverage left, BattingAverage right) { if(left.Average() == 0 ││ right.Average() == 0) return new BattingAverage(); else return new BattingAverage(left._atBats + right._atBats, left._hits + left._hits); } // Performs an OR operation on two batting averages public static BattingAverage operator │(BattingAverage left, BattingAverage right) { if(left.Average() != 0) return new BattingAverage(left._atBats, left._hits); else if(right.Average() != 0) return new BattingAverage(right._atBats, right._hits); else return new BattingAverage(); }

Эдгээр харьцуулах операторууд нь Average методыг орлох ба BattingAverage төрлийн объектуудыг ердийн төрлүүд шиг харьцуулах боломжийг олгож байна.

3.8 Өгөгдлийг далдлах - Проперти

Проперти нь классын гишүүн өгөгдлүүд рүү хандах боломж олгодог тусгай метод юм. Классыг хэрэглэгч нь объектын төлвүүд рүү методоор дамжуулалгүй шууд хандахыг хүснэ. Класс зохиогч нь классын дотоод төлвүүдийг далдалж методуудаар хандуулахыг хүснэ. Энэ тохиодолд хоёуланг хослуулсан шийдэл бол проперти тодорхойлох явдал юм. Энэ нь илүү төгс шийдэл юм. Пропертиг тодорхойлохдоо түүний төрөл, нэрийг бичээд хаалтан дотор get, set хандагчдыг тодорхойлно. set() метод нь value түлхүүр үгээр далд хэлбэрээр параметерээ хүлээн авна. public int Hour { get {

return hour; } set {

‐43‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 44: C# hicheelin lekts

C# хичээлийн лекцүүд

hour = value; } } Пропертийн утга болох hour хувьсагч нь өгөгдлийн санд хадгалагдаж байж болно, эсвэл локаль хувьсагч байж болно. Проперти тодорхойлоход get, set хандагчдыг хоёуланг заавал тодорхойлох шаардлагагүй бөгөөд, тухайлбал set хандагчыг тодорхойлоогүй тохиолдолд энэ нь зөвхөн уншигдах проперти болох юм. Проперти ашиглах нь объект-хандлагат загварчлалын өгөгдлийг далдлах шаардлагад нийцсэн оновчтой арга юм.

3.8.1 get хандагч

get хандагч нь пропертийн төрөлтэй ижил төрлийн утга буцаадаг методтой төстэй юм. Энэ нь пропертийн утгыг гишүүн хувьсагчийн утгаас авч буцаадаг. get {

return hour; } Энэ жишээнд локаль int төрлийн хувьсагчаас утгаа буцааж байна, мөн утгыг өгөгдлийн сангаас эсвэл ажиллах үедээ тооцоолж гарган авч болно.

3.8.2 set хандагч

set хандагч нь пропертийн утгыг оноож, void төрлийн утга буцаадаг методтой адил юм. set хандагчыг тодорхойлох үед дамжуулсан утгыг хүлээн авахдаа value түлхүүр үгийг ашиглана. Пропертид утга оноох үед set хандагч автоматаар дуудагдагдана.

3.9 Зөвхөн уншигдах талбарууд

Классын гишүүн өгөгдлийг зөвхөн уншигдах хандалттай тодорхойлж болно. Үүнийг readonly түлхүүр үгийн тусламжтай тодорхойлно. public static readonly int Year;         

‐44‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 45: C# hicheelin lekts

C# хичээлийн лекцүүд

Лекц№7.8

Удамшил ба Полиморфизм

Дэд сэдвүүд:

• Тусгайлал ба ерөнхийлөл

• Удамшил • Полиморфизм • Хаалттай класс (sealed class) • Бүх классын үндэс Object класс • Хайрцаглах • Интерфэйс • Төрөл таних

5.1 Тусгайлал ба Ерөнхийлөл

Классууд болон тэдгээрийн объектууд нь хоосон орчинд дангаар оршиж байдаг зүйлс биш юм, тэд бодит амьдралд байдаг юмстай адилаар өөр хоорондоо харилцан холбоо хамааралд оршдог. “Is-a” хэллэгээр илэрхийлэгдэж байгаа хамаарал бол тусгайлал (specialization) юм. Жишээлбэл, Dog is-a Animal (Нохой бол сүүн тэжээлтэн) гэсэн хэллэг нь нохой бол сүүн тэжээлтний нэг тусгай төрөл юм гэдгийг илэрхийлж байна. Нохой нь сүүгээр бойждог, үстэй зэрэг сүүн тэжээлтний шинжүүдийг агуулсан байдаг, гэхдээ гэрийн тэжээвэр шинжээрээ илүү тусгай юм. Муур мөн сүүн тэжээлтэн амьтан. Бид муур, нохой аль алинд байдаг шинжүүдийг ерөнхийлөөд сүүн тэжээлтэн гэж хэлдэг. Тусгайлах ба ерөнхийлөх хамаарлууд нь гүйцээлт ба удамшил юм. Тиймээс муур ба нохой нь сүүн тэжээлтний тусгайлал, сүүн тэжээлтэн нь муур ба нохойны ерөнхийлөл юм. Эдгээр хамаарал нь шаталсан шинжтэй байдаг. Тусгай шинжүүд нь ерөнхий шинжээсээ салаалж хамаарлын мод үүсгэдэг. Модны орой руу шилжихэд илүү ерөнхий шинжүүд гарна. Модноос доош шилжихэд илүү тусгай шинжүүдтэй болно.

‐45‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 46: C# hicheelin lekts

C# хичээлийн лекцүүд

UML- Unified Modeling Language Энэ номонд классуудын хамаарлын диаграмыг харуулахад UML хэлнээс ашигласан. UML (Нэгдсэн Загварчлалын Хэл) нь бизнес болон системийг загварчлах стандарт болсон хэл юм. Объект хандлагат системийн загварчлал хийхэд энэ хэл нь маш тохиромжтой байдаг. UML хэлэнд классууд нь хайрцаг хэлбэрээр дүрслэгдэнэ. Классын нэр нь хайрцгын дээд хэсэгт бичигдэнэ. Гишүүд нь хайрцаг дотор жагсаан бичигдэнэ. Зурагт харагдаж байгаагаар дээшээ сум нь тусгай классаас дээш илүү ерөнхий класс руу шилжиж байгааг харуулна.

5.2 Удамшил

C# хэлэнд тусгайлах хамаарал нь ерөнхийдөө удамшилаар хэрэгждэг. Удамшил нь тусгайлах хамаарлыг илэрхийлэх цорын ганц арга зам биш юм, гэхдээ энэ хамаарлыг илэрхийлэх хамгийн энгийн, нийтлэг арга юм. Өмнөх жишээнд WaterAnimal ба LandAnimal классууд нь Animal классаас тусгайлан гарсан өөрийн гэсэн шинжүүдтэй класс юм. Суурь классыг ийм аргаар тодорхойлох нь классуудын олонлогт шинэ амьтаны төрлүүдийг нэмэхэд хялбар байх юм. Жишээлбэл, Penguin класс нэмэхэд WaterAnimal классаас удамшуулж үүсгээд RentTuxedo методыг нэмэхэд л болох юм. Удамшлыг хэрэгжүүлэхдээ дараахь байдлаар гүйцэтгэнэ. public class Penguin : WaterAnimal

‐46‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 47: C# hicheelin lekts

C# хичээлийн лекцүүд

Удамшсан класс нь суурь классынхаа бүх гишүүдийг өвлөн авна, гишүүн хувьсагчид, гишүүн методууд. Удамшсан класс нь суурь классынхаа методыг шинээр хэрэгжүүлж болно. Үүнд new түлхүүр үгийг хэрэглэнэ. public class Penguin : WaterAnimal { // байгуулагч public Penguin() {

// ... } // SwimTo() методын шинэ хувилбар public new void SwimTo( ) {

// Penguin-ний сэлэлт } public void RentTuxedo() { // ... } }

5.2.1 Суурь классад хандах

C#-д тухайн объект руу this түлхүүр үгээр ханддаг бол түүний суурь класс руу base түлхүүр үгээр хандах боломжтой. Дараахь жишээнд CommandWindow классын PreDraw методыг дуудаж байна: class MyCommandWindow: CommandWindow { public void DrawShape() { base.PreDraw(); Draw(); } }

base түлхүүр үг нь зөвхөн дээд талын түвшний класс руу л хандах боломж олгоно. Өмнөх амьтадын жишээн дээр, Whale классаас base түлхүүр үгийг ашиглан Animal классын методыг дуудаж болохгүй гэсэн үг:

class Whale : WaterAnimal { // Won't work; the following line calls a WaterAnimal // method rather than a method from Animal. base.Eat(); }

base түлхүүр үг нь мөн класс дотор л бичигдэх ёстой, классын гадна хэрэглэж болохгүй:

// Won't work; base is not allowed in this context. BessieTheCow.base.GetPlansForWorldDomination();

5.3 Полиморфизм

‐47‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 48: C# hicheelin lekts

C# хичээлийн лекцүүд

Удамшилд хоёр хүчирхэг зүйл бий: Нэг нь кодыг дахин ашиглалт. Жишээ нь, ListBox классыг Window классаас удамшуулан үүсгэж суурь класс дахь зарим логикуудыг дахин ашиглах боломжтой. Удамшлыг хүчирхэг болгож байгаа өөр нэг зүйл нь полиморфизм (polymorphism) юм. Poly гэдэг нь олон, morph гэдэг нь хэлбэр гэсэн утгатай. Тиймээс полимофирзм гэдэг нь зүйлийн олон хэлбэртэй байхыг хэлнэ. Жишээ нь, гар утасны компани таны утас руу дуудах дохио илгээвэл шугамын цаана яг ямар төрлийн утас дугарахыг мэдэхгүй. Хуучин загварын мотороор хонх нь дуугардаг утас ч байж болно, эсвэл дижитал ая тоглуулах электрон утас ч байж болно. Гар утасны компаны мэдэж байгаа зүйл бол утасны үндсэн шинжийг (суурь класс) мэдэх бөгөөд тухайн утас (нэг объект) яаж дугарахаа өөрөө мэднэ гэдгийг мэдэж байгаа. Гар утасны компани таны утсанд дуугар (ring) гэж хэлж байгаа нь зүгээр л “тохирох зүйлээ хий” гэж хэлж байгаа юм. Тэгэхлээр гар утасны компани таны утсыг полиморф болгож байна. Өөрөөр хэлбэл нэг ижил мессеж (жишээ нь, ring) өгөхөд ялгаатай хэлбэрээр хэрэгжүүлэхийг полиморфизм гэж хэлнэ.

5.3.1 Полиморф төрөл үүсгэх

ListBox is-a Window, Button is-a Window учраас бид эдгээр төрлүүд дээр цонхны хийдэг зүйлсийг хийхийг хүсэж байгаа. Жишээлбэл, цонхны эдгээр бүх хувилбаруудыг нэг үндсэн цонх дээр байрлуулж түүнийг нээгдэх үед бүгд зурагдсан байх шаардлагатай байг. Үндсэн цонх нь аль элемент нь ListBox, аль нь Button гэдгийг мэдэхгүй, мэдэх шаардлагагүй, үүний тулд бүх элементүүдээр гүйж бүгдэд нь “зурах” командыг л өгнө. Товчхондоо, үндсэн цонх нь бүх цонх төрлийн объектуудыг полиморф байхыг хүснэ.

5.3.2 Полиморф метод үүсгэх

Полиморфыг дэмжих метод үүсгэхийн тулд суурь класс дотор түүнийг virtual гэж тэмдэглэх хэрэгтэй. Жишээлбэл, Window классын DrawWindow() методыг полиморф гэдгийг заахын тулд дараахь байдлаар зарлана. public virtual void DrawWindow( ) Ингээд удамшсан класс бүр өөрийн гэсэн DrawWindow() методыг хэрэгжүүлэх боломжтой болно. Үүний тулд суурь классын виртауль методыг override түлхүүр үг хэрэглэн удамшсан класс дотор дарж бичнэ. public override void DrawWindow( ) {

base.DrawWindow( ); // invoke the base method Console.WriteLine ("Writing string to the listbox: {0}", listBoxContents);

} Дараа нь Window, ListBox, Button төрлийн 3 объект үүсгээд тус бүрд нь DrawWindow() методыг дуудая. Window win = new Window(1,2);

‐48‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 49: C# hicheelin lekts

C# хичээлийн лекцүүд

ListBox lb = new ListBox(3,4,"Stand alone list box"); Button b = new Button(5,6); win.DrawWindow( ); lb.DrawWindow( ); b.DrawWindow( ); Энэ ажил нь яг хүссэнээр явагдаж бүх объектын хувьд тохирох DrawWindow() метод ажиллах болно. Гэвч энд полиморф хийгдээгүй байна. Жинхэнэ полиморф Window төрлийн массив үүсгэх үед харагдана. Window[] winArray = new Window[3]; winArray[0] = new Window(1,2); winArray[1] = new ListBox(3,4,"List box in array"); winArray[2] = new Button(5,6); Дээрх массивын бүх элемент дээр DrawWindow() методыг дуудах үед юу болох бол? for (int i = 0;i < 3; i++) {

winArray[i].DrawWindow( ); } Хэрэв DrawWindow() методыг виртуаль гэж тэмдэглээгүй бол Window классын DrawWindow() метод 3 удаа давтан дуудагдах болно. Гэвч виртуаль гэж тэмдэглэсэн учраас тухайн объект бүрийн тохирох метод ажиллах болно. Энэ бол полиморфизмын гол утга санаа юм.

5.3.3 Хийсвэр метод, хийсвэр класс

Хийсвэр методын зорилго нь виртуаль методтой ижил боловч удамшсан класс тухайн методыг заавал хэрэгжүүлэхийг (implement) шаарддагаараа ялгаатай юм. Виртауль методын хувьд үүнийг заавал шаардахгүй. Хэрэв хийсвэр метод нь уламшсан классаар хэрэгжээгүй бол уг классаас объект үүсгэж чадахгүй.

abstract public void ChaseAfterBadGuys();

Хэрэв нэг буюу түүнээс дээш тооны класс abstract гэж тэмдэглэгдсэн бол классын тодорхойлолт мөн abstract байх ёстой.

abstract public class Horse

Хийсвэр классыг хэрэгжүүлэхэд override түлхүүр үгийг ашиглан дараахь байдлаар тодорхойлно.

class Palomino : Horse { override public void ChaseAfterBadGuys() { } }

5.4 Хаалттай класс (sealed class)

‐49‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 50: C# hicheelin lekts

C# хичээлийн лекцүүд

Хийсвэр классын эсрэг хувилбар нь хаалттай (sealed) класс юм, ө.х бусад классын суурь класс болдоггүй. Классыг хаалттай зарласнаар хөрвүүлэгчид тухайн классыг хэзээ ч суурь класс болгон ашиглаж болохгүй гэдгийг хэлнэ.:

sealed class Horse { }

Ердийн тохиолдолд классууд нь хаалттай бус байдаг, учир нь хаалттай класс нь цаашид удамшуулан өргөтгөх боломжийг хаадаг. Хэдий тийм боловч, удамшлыг хориглож зөвхөн нэг л классыг тусгай зорилгоор үүсгэх шаардлага байж болно. Энэ нь итгэлтэй байдал эсвэл худалдааны зорилгоор шаардагдаж болно. Классыг хаах өөр нэг шалтгаан нь хурд, гүйцэтгэл юм. Хаалттай класс ачаалагдсан үед виртауль методууд байхгүй учраас CLR түүний методууд дээр хурдны оновчлолтууд хийж чадна.

C# нь мөн методыг хаалттай (sealed) байхыг зөвшөөрдөг, энэ нь удамшсан класс дотор түүнийг дарж тодорхойлохоос хамгаална.

5.5 Бүх классын үндэс Object класс

C# дахь бүх классууд Object классаас удамшиж төгсдөг. Мэдээж бүх классууд шууд Object классаас удамшихгүй, гэхдээ удамшлын модыг дамжин явбал эцэст нь Object дээр ирэх болно. Шинээр класс үүсгэхдээ ямар нэг удамшил заахгүй бол түүнийг Object классаас удамшсан гэж ойлгодог. Энэ нь дараахь хоёр тодорхойлолт адилхан гэсэн үг:

class Cat { } class Cat: object { } object төрөл нь .NET-н System.Object класстай ижил. .NET framework-н нэр ашигласнаас C# нэрийг нь ашигласан нь илүү дээр юм.

C#-н үндсэн төрлүүд мөн Object классаас удамшсан байдаг. Бүх төрлүүд нэг суурь класстай учраас зарим чухал үйлдлүүдийг бүгд дээр адилхан хийж болно. Жишээлбэл, C#-н бүх төрлүүд ToString() методыг дуудаж тэмдэгт мөр рүү хялбархан хувиргалт хийгддэг:

int n = 32; string stringValue = n.ToString()

Эсвэл утгууд дээр шууд хэрэглэж болно:

string stringValue = 32.ToString()

Өөр методууд мөн байна, GetType() нь объектыг санах ойд ажиллах үед ямар төрлийнх болохыг нь тодорхойлно. Мөн үлдэгдэл цэвэрлэгчтэй ажиллах, тэнцүүг шалгах, хувилах методууд энэ классад байдаг.

‐50‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 51: C# hicheelin lekts

C# хичээлийн лекцүүд

5.6 Хайрцаглах

Хайрцаглалт нь үндсэн төрлүүдийг заалт төрлүүд шиг ашиглах боломж олгодог. Үндсэн төрлийн хувьсагчид нь тухайн утгаа дүрслэх бит утгуудыг хадгалж байдаг. Тэгвэл яаж заалт төрөл шиг методууд хэрэглэж болоод байна вэ? Хариулт нь хайрцаглах процесс юм. Хайрцаглалт нь хувьсагчийг заалтын “хайрцаг” дотор байрлуулж заалт байдлаар ашиглах боломжтой болгодог.

Хайрцаглалт нь далд хэлбэрээр хийгддэг, жишээлбэл утат төрлийг объектод оноох үед. int Age = 42; object obj = Age; // Implicitly boxed Эсрэгээрээ, заалт төрлөөс үндсэн төрөл рүү хөрвүүлэх үед ил хэлбэрээр хөрвүүлэлт хийх шаардлагатай. Үүнийг хайрцгаас гаргах (unboxing) гэж нэрлэдэг. object obj; … int Age = (int)obj;

unboxing үйлдэлийн үед өгөгдөл алдагдах нөхцөл үүсч алдаа гарч болно. Жишээ нь, дараахь код нь InvalidCastException алдааг үүсгэнэ:

long feetPerLightYear; object obj = feetPerLightYear; int Age = (int)obj; // Not OK; overflows.

5.7 Интерфэйс

Интэрфэйс нь хийсвэр классын нэг хувилбар бөгөөд классууд болон тэдгээрийн хэрэглэгчийн хоорондох тохиролцоог тодорхойлдог. Интерфэйс бол класс ямар байхыг хэрэглэгчид илэрхийлсэн тохиролцоо юм. Интерфэйс нь гишүүн өгөгдөл байхгүй, үйлдлийн бие байхгүй тодорхойлолт.

5.7.1 Интерфэйсийг хэрэгжүүлэх

Интерфэйсийг interface түлхүүр үгийн тусламжтайгаар тодорхойлно. interface ISpeak { void StringToSpeech(string Message); void TextFileToSpeech(string FileName); }

‐51‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 52: C# hicheelin lekts

C# хичээлийн лекцүүд

Интерфэйсээс объект үүсгэж болохгүй. // Won't work; can't be instantiated directly. ISpeak speaker = new ISpeak();

Интерфэйсийг хэрэгжүүлсэн класс үүсгэх хэрэгтэй бөгөөд тэр классаас объект үүсгэж болно:

class Cat: ISpeak { } Cat anastasia = new Cat();

Энд Cat объектыг ISpeak төрлийн объект гэж ярих нь буруу юм, ISpeak интерфэйсийг хэрэгжүүлсэн объект гэж хэлэх нь зөв.

Интерфэйсийг хэрэгжүүлж байгаа класс нь түүний бүх методыг хэрэгжүүлэх үүрэгэй байдаг. class SpeechEngine: ISpeak { public void StringToSpeech(string Message) { } // TextFileToSpeech not implemented. }

Энэ жишээнд SpeechEngine класс нь TextFileToSpeech( ) методыг хэрэгжүүлээгүй байгаа учраас хөрвүүлэгч алдаа заах болно. Хэрэв SpeechEngine нь хийсвэр класс байсан бол энэ тохиолдолд хөрвүүлэгч алдаа заахгүй байх байсан.

Класс нь нэгээс илүү тооны интерфэйсийг хэрэгжүүлж болно.

public class Document : IStorable, ICompressible

5.7.2 Интерфэйсийг өргөтгөх

Шинэ метод, үйлдлүүдийг нэмэхийн тулд интерфэйсийг өргөтгөж болно. Доорх жишээнд ICompressible интерфэйсийг шинэ IloggedCompressible интерфэйсээр өргөтгөж байна. interface ILoggedCompressible : ICompressible {

void LogSavedBytes( ); }

5.8 Төрөл таних

‐52‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 53: C# hicheelin lekts

C# хичээлийн лекцүүд

Классууд нь бие биенээсээ удамшиж, интерфэйс хэрэгжүүлж хувьсан өөрчлөгдсөн байдаг. Тэгвэл нэг объектыг ямар төрлийн, ямар классын объект болохыг тодорхойлох шаардлага гарна.

5.8.1 is үйлдэл

is үйлдэл нь объект нь өгөгдсөн төрлийнх мөн эсэхийг шалгахад хэрэглэгддэг. Үр дүн болох утга нь логик төрөлтэй байна. public void DisplayObject(object obj) { if(obj is BattingAverage) { // obj refers to a BattingAverage object. } }

5.8.2 as үйлдэл

as үйлдэл нь is ба төрөл хувиргах (cast) операторуудын хослол оператор юм. Эхлээд is шалгалт хийгээд дараа нь төрөл хувиргалт хийнэ. Хэрэв хувиргалт амжилтгүй болвол null утга буцаана. static void Main( ) {

Document doc = new Document("Test Document"); IStorable isDoc = doc as IStorable; if (isDoc != null)

isDoc.Read( ); else

Console.WriteLine("IStorable not supported"); ICompressible icDoc = doc as ICompressible; if (icDoc != null)

icDoc.Compress( ); else

Console.WriteLine("Compressible not supported"); }

5.8.3 typeof үйлдэл

typeof үйлдэл нь програм ажиллах үеийн классын төрлийг тодорхойлоход хэрэглэгдэнэ. Энэ үйлдэл нь объект бус төрөл дээр хэрэглэгдэнэ. Үр дүн нь System.Type төрлийн объект байна. Type theType = typeof(BattingAverage);      

‐53‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 54: C# hicheelin lekts

C# хичээлийн лекцүүд

Лекц№9

Алдаа барих Дэд сэдвүүд

• Алдаа барих • Алдааны мэдээллүүдийг ашиглах • Олон алдаа баригч • finally блок • .NET Framework-н алдааны классууд

Объект хандлагат програмчлалын хэлнүүдэд байдагтай адилаар C# нь алдаанууд болон хэвийн бус нөхцөлүүдийг алдааны объектоор боловсруулдаг. Алдааны объект гэдэг нь програмын хэвийн бус тохиолдлуудын тухай мэдээллийг агуулсан объект юм. Алдааны объект (exception), алдаа (error), цоорхой (bug) гэсэн ухагдахуунуудыг ялган ойлгох нь чухал юм. Цоорхой гэдэг нь програм зохиогчийн хийсэн алдаа. Алдааны объект бол цоорхойгоос зайлах хамгаалалт биш юм. Түүнчлэн, цоорхой нь алдааны объект шидэгдэх шалтгаан нь байж болох юм, алдааны объектыг цоорхойгоо хянахад ашиглах ёсгүй. Харин цоорхойг засах хэрэгтэй. Алдаа бол хэрэглэгчийн үйлдлээр хийгдэнэ. Жишээлбэл, хэрэглэгч тоо оруулах ёстой байтал үсэг оруулах. Алдаа нь мөн алдааны объект үүсгэх шалтгаан байж болох юм. Аль болох алдааг шалган гарах нөхцөлүүдийг хаах хэрэгтэй. Ингээд бүх алдаа гарах нөхцөл, цоорхойнуудыг хаасны дараа ч програм тооцоолоогүй асуудалд орж болно, тухайлбал, санах ой хэтрэх эсвэл файл систем дээр байхгүй файл руу хандахыг оролдох гэх мэт. Алдааны объектоос хамгаалж чадахгүй, харин програмаа бүр унагахгүйн тулд түүнийг боловсруулж болно. Програм санах ой дүүрэх гэх мэт тооцоолоогүй онцгой тохиолдолд ороход алдааны объектыг шиддэг. Алдааны объект шидэгдсэн үед тухайн функц тасарч түүнийг барих хүртэл дээд түвшний функцүүд рүү дамжин шидэгдэх болно. Энэ нь хэрэв тухайн функц алдааны объектыг барихгүй бол түүнийг дуудсан функцэд барих боломж олдоно, хэрэв дуудсан функцүүдээс аль нь ч барихгүй бол эцэст нь CLR –ээр баригдаж програмыг таслахад хүрнэ гэсэн үг.

6.1 Алдааг барих

Алдааг барихын тулд алдаа гарч болох кодоо try блок дотор бичих ба гарсан үед алдааны объектыг боловсруулах кодыг catch блок дотор бичнэ. try { Dog d; // Attempt to call through a null reference. d.ChaseCars(); } catch { // Handle any exception. }

‐54‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 55: C# hicheelin lekts

C# хичээлийн лекцүүд

try блок дотроос алдаа шидэгдсэн үед тухайн алдаанд тохирох алдааны объект үүсэж түүнийг барихад тохирох catch блокоо хайдаг. Дээрх жишээнд catch блок нь объектын төрлийг заагаагүй учраас ямар ч төрлийн алдааны объектыг барина. Програмын удирдлага catch блок руу шилжихэд дараахь арга хэмжээнүүдийг авч болно:

• Алдааны объектыг боловсруулж catch блокын дараагийн кодоос програмын биелэлтийг үргэлжлүүлэх

• Алдааны объектыг дахин шидэх

Тусгай алдааны объектыг барихын тулд шүүлтүүрийн үүргээр ажиллах параметерыг catch блокод хэрэглэж болно:

try { Dog d; // Attempt to call through a null reference. d.ChaseCars(); } catch(NullReferenceException ex) { // Handle only null reference exceptions. }

Хэрэв catch блок алдааны объектыг танихгүй бол алдааны объект цааш үргэлжлэн шидэгдэх болно. Хэрэв catch блок танихгүй бол алдааны объектыг дахин шидэх ёстой бөгөөд энэ нь өөр нэг тохирох алдаа баригчаар баригдах нь зөв юм.

Алдааг дахин шидэхийн тулд throw түлхүүр үгийг алдааны объекттой хамт хэрэглэнэ:

try { Dog d; // Attempt to call through a null reference. d.ChaseCars(); } catch(NullReferenceException ex) { // (ex); Log error information. LogError (ex); // Rethrow the exception. throw(ex); }

Тухайн алдааны объектыг цааш шидэхэд throw түлхүүр үгийг параметергүй хэрэглэж болно:

catch(NullReferenceException ex) { // Rethrow the current exception. throw; }

Алдааны объект дахин шидэгдсэн үед түүнийг барих боломжтой дараагийн catch блок олдох хүртэл хайдаг. Дуудалтын стекийн буцах чиглэлээр алдааны объект нь цааш шидэгдэх бөгөөд түүнийг барих хүртэл энэ нь үргэлжлэнэ. Хэрэв барих код олдохгүй бол програм тасрах болно.

‐55‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 56: C# hicheelin lekts

C# хичээлийн лекцүүд

6.2 Алдааны мэдээллүүдийг ашиглах

Алдааны объектоос ToString методыг хэрэглэж алдааны тухай дэлгэрэнгүй мэдээллийг авч болно:

catch(InvalidCastException badCast) { Console.WriteLine(badCast.ToString()); }

Алдааны объектод мөн бусад мэдээллүүд ч байна:

• StackTrace - алдааны объект баригдсан цэг хүртэлх явсан стекийн замыг харуулна

• InnerException - алдааны объектыг шидэх явцад нэмэгдсэн нэмэлт объектыг буцаана

• Message – алдааны объектыг тодорхойлсон тэмдэгт мөр • HelpLink – алдааны объектын талаар нэмэлт мэдээлэлд хүргэх URL буюу

Universal Resource Name (URN)

Хэрэв програм зохиогч өөрийн гэсэн алдааны класс үүсгэх бол дээрх мэдээллүүдийг заавал багтаах хэрэгтэй..NET Framework-н алдааны объектуудад байдагтай ижил мэдээллүүдээр хангаснаар таны класс илүү ашиглаж болохуйц байх болно.

6.3 Олон алдаа баригч

Хэрэв код нэгээс олон төрлийн алдааны объект шидэх магадлалтай бол тэдгээрт тохирох олон catch блок нэмэгдэх ёстой. Ямар ч төрлийн алдааг барих блокыг хэрэглэсэн үед хамгийн сүүлд байрлуулах нь зүйтэй:

try { Dog d = (Dog)anAnimal; } catch(NullReferenceException badRef) { // Handle null references. } catch(InvalidCastException badCast) { // Handle a bad cast. } catch { // Handle any remaining type of exception. }

Ерөнхий тохиолдолд catch блокуудыг дараалуулан байрлуулахдаа ерөнхий шинжтэй catch блокуудыг тусгай шинжтэй catch блокуудын ард байрлуулах зарчмыг барих нь зүйтэй:

try { Dog d = (Dog)anAnimal; } catch(Exception ex) { // Handle any exception. }

‐56‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 57: C# hicheelin lekts

C# хичээлийн лекцүүд

catch(InvalidCastException badCast) { // Handle a bad cast. }

Энэ жишээнд эхний catch блок нь бүх төрлийн алдааны объектыг барих учраас хоёр дахь блок руу ямар ч алдааны объект дамжигдахгүй, тиймээс буруу хөрввүүлэлтийг барих кодын хэсэг ажиллахгүй болно. Энэ нь илэрхий алдаа учраас хөрвүүлэгч ийм хэлбэрийн кодыг зөвшөөрөхгүй.

Алдаа баригчуудыг үүрлүүлэн хэрэглэж болно:

try { Animal anAnimal = GetNextAnimal(); anAnimal.Eat(); try { Dog d = (Dog)anAnimal; d.ChaseCars(); } catch(InvalidCastException badCast) { // Handle bad casts. } } catch { // General exception handling }

Алдааны объект үүссэн үед доторх блок ажиллана, хэрэв алдаа баригдалгүй дахин шидэгдсэн бол гаднах блок түүнийг барих болно.

6.4 finally блок

Метод бичих үед зарим тохиолдолд дуудагч руу удирдлагыг шилжүүлэхээс өмнө зайлшгүй хийх ёстой үйлдлүүд гардаг. Энэ нь ихэвчлэн нөөцийг чөлөөлөх, файл, урсгалуудыг хаах гэх мэт үйлдлүүд байдаг. C# -д үүнийг finally блокоор хийдэг:

try { Horse silver = GetHorseFromBarn(); silver.Ride(); } catch { } finally { silver.Groom(); }

Энэ жишээнд finally блок нь алдааны объект шидэгдсэний дараа ажиллана. finally блок нь мөн return, goto, continue, эсвэл break заавруудаар програмын удирдлагыг sөөрчилсөн ч биелэх болно.

‐57‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 58: C# hicheelin lekts

C# хичээлийн лекцүүд

Энд харагдаж байгаагаар finally блок нь try блоктой залгагдсан хамт бичигдсэн байна. Хэрэв catch блок дотроос алдааны объектыг дахин шидсэн бол методын биелэлтээс гарахын өмнө эхлээд finally блок руу удирдлага шилжих болно.

6.5 .NET Framework-н алдааны классууд

.NET Framework нь маш том алдааны классын сантай. Бүх алдааны класс нь Exception классаас удамшсан байдаг ба алдааны классууд нь ямар сангаас үүсэх алдаа гэдгээрээ ангилагдан тухайн сандаа харъяалагддаг. Жишээлбэл, IO классуудаас шидэгдэх алдааны классууд System.IO сан дотор байрлана.

.NET Framework дэх алдааны классууд нь ихэвчлэн шууд System.Exception классаас удамшсан байдаггүй. Харин, төсөөтэй алдааны классуудаар ангилагдсан байдаг. Жишээлбэл, бүх оролт/гаралтын алдааны классууд нь System.IO.IOException классын дэд классууд юм, System.IO.IOException нь өөрөө System.Exception классаас удамшсан. Энэхүү удамшлын хамаарал нь оролт/гаралтын төрлийн алдаануудыг алдаа бүрд тохирсон catch блок бичилгүйгээр нэг блокоор барих боломжийг олгоно:

catch(IOException ioError) { // Handle all IO exceptions here. }

Програм зохиогч өөрийн алдааны классуудыг зохиох үедээ шууд System.Exception классаас удамшуулалгүйгээр энэ дүрмийг барих нь зүйтэй.

                      

‐58‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 59: C# hicheelin lekts

C# хичээлийн лекцүүд

Параллель програмчлал Дэд сэдвүүд:

• Програмын муж • Програмын зам

Бид үйлдлийн систем нэгэн зэрэг хэд хэдэн ажил хийж чадна гэдгийг мэднэ. Word дээр юм бичих үед өөр програм файл татаж, баримт хэвлэж, дуу тоглуулж байдаг. Мөн нэг програм нэгэн зэрэг олон ажил хийж байдаг. Жишээлбэл, дууны програм нэгэн зэрэг сүлжээнээс аудио өгөгдөл уншиж, түүнийгээ задалж, тоглуулж, дэлгэцэн дээр харуулж байдаг. Ийм зүйлүүдийг хийх чадвартай програмыг параллель боловсруулалттай12 програм гэдэг.

13Параллель програмчлалд 2 үндсэн ойлголт байдаг: процесс ба зам . Замууд бол санах ойд параллель ажиллаж байгаа биелэх кодын судлууд юм. Програм бүр ядаж нэг код ажиллуулах замтай байна. Програм нь мөн олон замтай байж болно.

Компьютерийн систем нь олон идэвхитэй процесс, замуудыг агуулдаг. Нэг процессортой системийн хувьд тухайн эгшинд зөвхөн нэг л замыг биелүүлэх юм. Нэг процессортой тохиолдолд процессууд, замууд процессорыг хуваан эзэмших ба ингэхдээ хугацаагаар хуваах14 аргыг ашигладаг.

Одоо үед олон процессор, олон биелүүлэгчтэй компьютерүүд бий болсон. Энэ нь параллелт боловсруулалтын багтаамжыг үлэмж нэмэгдүүлдэг. Гэхдээ нэг процессортой энгийн системийн хувьд ч параллель боловсруулалт нь боломжтой юм.

8.1 Програмын муж

CLR нь програмыг application domain гэж нэрлэгдэх логик процесс дотор ажиллуулдаг. Програмын муж гэдэг нь програмын эзэмшиж байгаа хил хүрээг заагласан тусгаарлалт юм. Програмын мужийн тусламжтайгаар процессуудыг хянахад хялбар болдог. Програм болгон өөрийн мужтай ажилладаг бөгөөд мужууд хооронд физик процессуудыг хуваан эзэмшиж болно.

8.2 Програмын зам

Нэг програмын муж дотор хэд хэдэн зам ажиллаж болно. System.Threading.Thread класс нь програмын зам үүсгэхэд зориулагдсан. Програм эхлэхэд програмын муж нь үндсэн нэг замтайгаар эхлэнэ. Thread классын CurrentThread пропертиг дуудаж тухайн ажиллаж байгаа замыг мэдэж болно:

Thread currentThread = Thread.CurrentThread;

Ажиллаж байгаа замыг тодорхой хугацааны турш зогсооход Sleep статик методыг ашиглана:

                                                 12 concurrent 13 thread 14 Time slacing 

‐59‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 60: C# hicheelin lekts

C# хичээлийн лекцүүд

Thread.Sleep(5000);

Шинэ зам үүсгэхийн тулд эхлээд дараахь жишээнд үзүүлснээр шинэ Thread объект үүсгэнэ:

static void Main(string[] args) { Thread currentThread = Thread.CurrentThread; Thread workThread = new Thread(new ThreadStart(Work)); } static void Work() { Console.WriteLine("Hello"); }

Thread байгуулагч нь ThreadStart төлөөлөгчийг параметер болгон хүлээн авдаг. Замыг эхлүүлэхэд энэ төлөөлөгчийн зааж байгаа метод дуудагдаж ажиллах ба методоос гарахад замын ажиллагаа дуусна.

ThreadStart төлөөлөгчийн заах метод нь статик эсвэл статик бус байж болно. Дараахь Worker классыг үүсгэе:

public class Worker { protected string _message; public string Message { set { _message = value; } get { return _message; } } public void PrintMessage() { Console.WriteLine("Message from worker: {0}.", _message); } }

Worker классыг ашиглах Thread объект үүсгэх бол Worker объектыг эхлээд үүсгэх хэрэгтэй:

static void Main(string[] args){ Worker w = new Worker(); w.Message = "Hello from the worker thread"; Thread workerThread = new Thread(new ThreadStart(w.PrintMessage)); }

Thread объектыг үүсгэсний дараа Start методыг дуудаж замыг эхлүүлнэ:

workerThread.Start();

Зам нь үйлдлийн системээр хянагдаж ажиллах ба ThreadStart төлөөлөгчийн метод дуусах буюу хүчээр өөр газраас зогсоох хүртэл ажиллах болно.

Замын биелэлтийг түр зогсооход Suspend методыг хэрэглэж болно:

workerThread.Suspend();

‐60‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 61: C# hicheelin lekts

C# хичээлийн лекцүүд

Хэрэв дуудах үед уг зам эхлээгүй эсвэл ажиллаад дууссан бол ThreadStateException алдааны объект шидэгдэх болно. Замын тухайн үеийн төлөвийг ThreadState пропертигоор мэдэж болно. Дараахь хүснэгтэд замын төлвүүдийг харуулав.

Төлөв Тайлбар Aborted Замыг тасалсан AbortRequested Өөр замаас тухайн замыг таслах хүсэлт ирсэн

Зам нь ард ажиллах зам (background thread) байдлаар ажиллаж байна Background

Running Зам ажиллаж байна Stopped Замын ажиллагаа зогссон StopRequested Зам зогсох хүсэлт илгээсэн Suspended Зам түр зогссон SuspendRequested Түр зогсоох хүсэлт илгээсэн Unstarted Зам үүссэн, гэхдээ эхлээгүй

Зам түгжигдсэн эсвэл түр зогссон эсвэл өөр зам холбогдохыг хүлээж байна WaitSleepJoin

Дээрх хүснэгт дэх төлвүүд нь ихэвчлэн хосолж хэрэглэгддэг.

                            

‐61‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 62: C# hicheelin lekts

C# хичээлийн лекцүүд

ЛЕКЦ№11 ЦОНХТОЙ ПРОГРАМ

Цонхнууд

Дэд сэдвүүд: • Цонхны хэлбэрүүд • Цонхтой програм үүсгэх • Clipboard • Drag and Drop

Windows програмчлалын эхэн үед програмууд тусдаа компьютерүүд дээр ажилладаг байсан. Цаг хугацаа өнгөрөхөд програм зохиогчид хэрэглэгчийн интерфэйстэй хэсэг нь тусдаа нэг компьютер дээр, өгөгдлийн сантай хэсэг нь өөр нэг компьютер дээр сүлжээгээр холбогдон ажиллах нь илүү давуу талтай юм байна гэдгийг олж мэдсэн. Програмыг ингэж үүргийн хувьд тусгаарлаж байгааг 2-давхаргат (two-tier) буюу клиент/сервер хөгжүүлэлт гэж нэрлэсэн байна. Сүүлд энэ нь 3-давхаргат эсвэл n-давхаргат зэргээр нэрлэгдэж вэб үйлчилгээнүүдийг ашиглаж эхэлсэн. Хамгийн анхны Вэб програм гарч ирэх үед Windows програм болон Web програмын хооронд тодорхой ялгаа зааг бий болсон. Windows програм нь десктоп эсвэл локаль сүлжээнд ажиллана, Web програм нь алсын сервер дээр ажиллах ба браузерээр хандана. Энэ ялгаа одоо улам арилж байна. Одоо Windows ба Web програмыг ялгах үндсэн ялгаа бол хэрэглэгчийн интерфэйсийг хэн эзэмшиж байна гэдгээр ялгагдаж байна. Програмын хэрэглэгчийн интерфэйсийг харуулахад браузер ашиглаж байна уу? Эсвэл график интерфэйс дээр тулгуурласан биелэх програм уу? Миний бодлоор Windows ба Web програмын хооронд байгаа энэ ялгаа нь түр зуурын юм. Дараагийн үеийн хөгжүүлэлтийн хэрэгслүүд дээр энэ ялгаа байхгүй болно гэдэгт итгэлтэй байна. Windows програмууд хийхэд Windows Forms -ыг ашигладаг, Web програм хийхэд Web Forms-ыг ашигладаг. System.Windows.Forms сан нь цонхтой хэрэглэгчийн интерфэйс бүхий програмуудыг зохиоход зориулагдсан баялаг сан юм. Энэ сан дахь Form класс нь бүх төрлийн диалог, цонх классуудын суурь класс нь юм.

1.1 Цонхны хэлбэрүүд Form-г ашиглах хамгийн энгийн хэрэглээ нь хэрэглэгчтэй харилцан ажиллах диалог цонх юм. Диалоги цонх нь ердийн текст агуулсан энгийнээс эхлээд олон тооны контрол агуулсан нийлмэл хүртэл байдаг. Зарим диалоги цонхнууд үйлдлийн системийн нэг хэсэг болж багтсан байдаг. Ийм диалоги цонхнуудыг үндсэн диалоги цонх (common dialog box) гэж нэрлэдэг, энд жишээлбэл, өнгө сонгох, фонт сонгох, принтерийн тохиргоо хийх гэх мэт цонхуудыг нэрлэж болно.

‐62‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 63: C# hicheelin lekts

C# хичээлийн лекцүүд

Диалоги цонхууд нь ихэнхи тохиолдолд хэрэглэгчид мэдээлэл хийхэд хэрэглэгддэг. Үүнд зориулж мессежийн цонхыг ашигладаг. .NET-д MessageBox классыг ашиглан ийм хэлбэрийн цонхыг харуулж болно. Ердийн цонхтой програм нь нэгээс олон тоонын цонхуудтай ажилладаг, мөн хүү цонхуудтай байж болно. Цонхыг харуулахдаа 2 хэлбэрээр харуулж болно.

• Модаль цонх (modal form) – ийм цонх нээгдсэн үед програмын бусад хэсгүүдтэй ажиллах боломжгүй болно. Ийм хэлбэрийн цонх нь програмыг цааш үргэлжлүүлэхэд шаардлагатай мэдээллийг хэрэглэгчээс асуухад тохиромжтой.

• Ердийн цонх (modeless form) – ийм цонх нээгдсэн үед програмын бусад хэсгүүдтэй ажиллах боломжтой. Ийм хэлбэрийн цонх нь удаан хугацааны туршид ашиглахад тохиромжтой.

Модаль цонхны жишээнүүд бол алдааны мэдээлэл харуулах мессежний цонх, файл нээх, хадгалах диалоги цонхнууд юм. Ердийн цонхны жишээнд хэрэглэгч ажиллах боломж бүхий Microsoft Word програмын хүү цонхнуудыг нэрлэж болно. Ихэнхи тохиолдолд модаль бус цонхуудыг програмд ашигладаг бөгөөд хэрэглэгчээс лавлаж байж програм цааш үргэлжлэх шаардлагатай хэсгүүдэд модаль цонхуудыг ашиглах нь тохиромжтой юм.

1.1.1 Модаль ба модаль бус цонх Цонхыг модаль эсвэл модаль бус хэлбэр нь түүнийг яаж харуулснаас хамаарна. Ердийн цонх харуулахад Show методыг дараахь байдлаар хэрэглэнэ. Form addressForm = new AddressForm(); addressForm.Show();

Цонхыг програмын замаар хаахдаа Close методыг хэрэглэж болно:

addressForm.Close();

Мөн өөр нэг хэлбэр нь Hide методыг ашиглан харагдахгүй болгож болно:

addressForm.Hide();

Модаль цонх харуулахын тулд ShowDialog методыг ашиглана:

addressForm.ShowDialog(); ShowDialog методын дуудалт нь хэрэглэгчээс хариу өгөх хүртэл дуусахгүй. Диалоги цонхноос хэрэглэгч ямар сонголт хийснийг DialogResult тогтмолуудын тусламжтай таньж болно. Form addressForm = new AddressForm(); DialogResult result = addressForm.ShowDialog(); if(result == DialogResult.OK) { // Dialog box contents are valid. }

DialogResult тоочих төрөл нь дараахь тогтмол утгуудыг агуулна:

‐63‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 64: C# hicheelin lekts

C# хичээлийн лекцүүд

• Abort • Cancel • Ignore • No • None • OK • Retry • Yes

Энэ буцах утга нь ихэвчлэн хэрэглэгчийн дарсан товчны утга байх юм. Жишээлбэл, хэрэглэгч Esc товч дарсан бол DialogResult.Cancel утга буцаах болно.

1.1.2 Мессеж цонх Мессеж цонхыг харуулахдаа MessageBox классын Show методыг ашиглана. MessageBox.Show("A simple message box");

Show методын дээрх хувилбар нь хамгийн энгийн мессеж цонхыг харуулна, параметерээр дамжуулсан текст ба OK товчлуур.

Илүү олон боломжууд, товчнууд, зургуудыг харуулж чадах Show методын 12 янзын хувилбар байдаг.

Мессеж цонхонд гарчиг хийхийн тулд хоёр дахь параметерыг нэмж дараахь байдлаар хэрэглэнэ:

MessageBox.Show("A simple message box", "MessageBox demo");

Мессеж цонх нь OK товчноос өөр олон товчнуудтай байж болно, энэ нь хэрэглэгчээс олон төрлийн хариулт авах боломж олгоно. Мессеж цонхон дээр 3 хүртэлх товч байж болно, эдгээр товчнуудыг өөрөө үүсгэх шаардлагагүй MessageBoxButtons тоочих төрөлд заасан утгуудыг ашиглана.

• AbortRetryIgnore - Abort, Retry, Ignore товчнууд • OK – Ok • OKCancel – Ok, Cancel • RetryCancel – Retry, Cancel • YesNo – Yes, No • YesNoCancel – Yes, No, Cancel

Дараахь кодонд олон сонголттой мессеж цонхыг харуулж байна:

DialogResult result = MessageBox.Show("A message box with 3 buttons", "MessageBox demo",

‐64‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 65: C# hicheelin lekts

C# хичээлийн лекцүүд

MessageBoxButtons.YesNoCancel); switch(result) { }

MessageBoxIcon тоочих төрөл нь мессеж цонхонд дүрслэгдэх зургуудын (icon) олонлогыг агуулна.

Гишүүн Тайлбар

Asterisk

Error

Exclamation

Hand Error-той адил. Information Asterisk-тай адил. None Icon дүрслэгдэхгүй.

Question

Stop Error-той адил Warning Exclamation-тэй адил

Мессеж цонхыг дээрх icon-уудтай харуулахад дараахь байдлаар хэрэглэнэ:

DialogResult result = MessageBox.Show("A message box with an icon", "MessageBox demo", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Asterisk); switch(result) { }

1.1.3 SDI, MDI

1.2 Цонхтой програм үүсгэх Application класс нь цонхтой програмуудыг удирдахад хэрэглэгдэнэ. Програмыг эхлүүлэх, дуусгах зэрэгт уг классын Run, Exit зэрэг статик методуудыг хэрэглэнэ. Жишээлбэл, Run методыг ашиглан програмыг дараахь байдлаар эхлүүлж болно. Application.Run(new Form1());

Run методын 3 хувилбар байдаг. Дээрх жишээнд хамгийн өргөн хэрэглэгддэг хувилбарыг харуулсан байна. Run метод нь мэдэгдэл боловсруулагчийг (message loop) эхлүүлж параметер болгон дамжуулсан цонхыг харуулна. Microsoft Visual Studio .NET –ээр Windows Forms project үүсгэх үед Run методын энэ хувилбарыг ашигладаг.

Мөн өөрөөр, Run методыг параметергүйгээр дуудаж болно:

Application.Run();

‐65‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 66: C# hicheelin lekts

C# хичээлийн лекцүүд

Run методыг параметергүй дуудсан үед мэдэгдэл боловсруулах процессийг эхлүүлэх боловч цонх харуулахгүй. Run методын энэ хувилбар нь цонхоо сүүлд харуулахад зарим тохиолдолд хэрэгтэй байдаг.

Run методын гуравдахь хувилбар нь ApplicationContext объект хүлээн авдаг. Run методын өмнөх хувилбаруудад ApplicationContext мөн далд ашиглагдах бөгөөд үндсэн цонхыг хаах үед програмыг автоматаар хаах зэрэг үүргийг гүйцэтгэдэг. Програм зохиогч ApplicationContext классаас удамшуулан өөрийн тусгай шинж бүхий хувилбарыг үүсгэж болно. Дараахь жишээнд ApplicationContext классаас удамшсан, програмыг хаах шинжийг өөрчилсөн шинэ класс үүсгэсэн байна:

public class QueryApplicationContext: ApplicationContext { private string _saveMessage = "Exit and discard changes?"; private string _caption = "Application Exit"; public QueryApplicationContext(MainForm form) { form.Show(); form.Closing += new CancelEventHandler(FormClosing); } private void FormClosing(object sender, CancelEventArgs e) { DialogResult result = MessageBox.Show(saveMessage, _caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if(result == DialogResult.Yes) { ExitThread(); } else { e.Cancel = true; } } }

Энэ жишээнд FormClosing метод нь програмын үндсэн цонхны Closing үзэгдлийг боловсруулж байна. Closing үзэгдэл нь цонх хаагдах үед үүсдэг ба CancelEventArgs объектыг параметер болгон дамжуулдаг. FormClosing метод дотор хэрэглэгчээс лавлагаа асуусан мэдэгдлийн цонх харуулж байна. Хэрэглэгч Yes товч дарсан бол ExitThread дуудагдаж програмыг таслана, хэрэв No дарсан бол Closing үзэгдэл цуцлагдах болно.

Энэ классаа ашиглахын тулд түүнээс объект үүсгэж Application.Run методод дараахь хэлбэрээр дамжуулна:

static void Main() { MainForm form = new MainForm(); QueryApplicationContext appContext; appContext = new QueryApplicationContext(form); Application.Run(appContext); } 1.2.1 Програмын замыг тодорхойлох

Програмд шаардлагатай файлуудыг байрлуулах үед түүний замыг мэдэх шаардлага гардаг. Application класс нь програмын зам, програмын өгөгдлийг хадгалсан хавтасуудын мэдээллийг тодорхойлоход ашиглагдах методуудыг агуулна.

‐66‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 67: C# hicheelin lekts

C# хичээлийн лекцүүд

Програм ачаалагдсан байрлалыг тодорхойлоход ExecutablePath пропертиг ашиглана:

string executablePath = Application.ExecutablePath;

Програм эхэлсэн хавтасын байрлалыг авахад StartupPath проперти ашиглана:

string startupPath = Application.StartupPath;

Windows програмуудын хувьд өгөгдөл нь хандахад хялбар байхаар тусгай байрлалд байдаг. Програмын өгөгдөл нь Documents And Settings хавтасын дэд хавтас болон байрлах ёстой (Documents And Settings\<user_name>). Өгөгдлийг ийм байдлаар хадгалах нь нэг байрлалаас бүх өгөгдөлдөө хүрэх боломжийг олгоно. Application класс нь эдгээр замыг тооцоолоход туслана.

Нийтийн хавтасыг тодорхойлоход CommonAppDataPath пропертиг ашиглана:

string commonDataPath = Application.CommonAppDataPath;

Зам нь Documents And Settings\All Users\Application Data хавтас дотор <company_name>\<product_name>\<version> дэд хавтас хэлбэрээр олдоно. Компани болон бүтээгдэхүүний нэр зэрэг мэдээллийг AssemblyInfo.cs файл дотор програм зохиогч зааж өгнө.

Тусгай хэрэглэгчийн хавтасыг тодохойлоход UserAppDataPath пропертиг ашиглана:

string userDataPath = Application.UserAppDataPath;

Энэ зам нь нийтийн замтай ижил дүрмээр байрлах ба ялгаа нь тусгай нэг хэрэглэгчийн мэдээлэлд хүрэхэд зориулагдсан. Жишээлбэл, Ali нэртэй хэрэглэгчийн хувьд програмын өгөгдөл Documents And Settings\Ali\Application Data хавтас дотор байрлана.

1.2.2 Сул зогсолт

Мэдэгдэл болвсруулагч ямар нэг ажил гүйцэтгэлгүй сул зогссон үед Idle гэж нэрлэгдэх тусгай үзэгдэл үүсдэг, энэ үед доогуур-зэрэглэлтэй (low-priority) ажлуудыг гүйцэтгэх боломж бүрдэнэ. Тухайлбал, Idle үзэгдэл үүссэн үед төлвийн мөр зэрэг хэрэглэгчийн интерфэйсийн хэсгүүдийг шинэчлэх ажлуудыг хийж болно.

Idle үзэгдлийг боловсруулах EventHandler төрлийн метод тодорхойлох хэрэгтэй:

private void OnIdle(object sender, EventArgs e) { // Perform idle processing here. }

Idle үзэгдлийг барих захиалга хийхийн тулд дээрх методыг Application.Idle үзэгдэл баригчид нэмэх хэрэгтэй:

MyForm() { Application.Idle += new EventHandler(OnIdle); } 1.2.3 Програмыг дуусгах

‐67‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 68: C# hicheelin lekts

C# хичээлийн лекцүүд

Анхны төлөвөөрөө үндсэн цонхыг хаахад програмын ажиллагаа дуусдаг. Өмнө дурдсанаар мөн ApplicationContext классаар энэ шинжийг өөрчилж болно. Өөр нэг арга зам бол Application классыг шууд ашиглаж болно.

Application класс нь програмыг дуусгах мэдэгдэлийг өгөх Exit методыг агуулна. Exit метод нь ямар ч thread -ээс дуудагдаж болно:

Application.Exit();

Exit метод нь програмыг шууд дуусгах метод биш юм, энэ метод дуудагдсан үед бүх мэдэгдэлүүд хаагдаж Run метод дуусах юм. Run метод дуусах нь програмын ажиллагаа дуусахтай адил бөгөөд зарим тохиолдолд түүний дараа програмд ашиглагдсан нөөцүүдийг цэвэрлэх кодууд байж болдог.

static void Main() { Application.Run(new Form1()); appMutex.Close(); stream.Close(); }

Ерөнхийдөө Exit методыг шууд дуудах хэрэггүй, учир нь энэ нь нээлттэй байгаа цонхуудыг шууд хаадаг. Цонхтой програмыг дуусгах хамгийн оновчтой арга бол үндсэн цонхны Close методыг дуудах юм.

Програмын тодорхой замыг дуусгахад ExitThread методыг ашиглана:

if (Application.MessageLoop == true) Application.ExitThread();

Энд MessageLoop проперти нь тухайн thread-д мэдэгдэл боловсруулалт бйагаа эсэхийг шалгана.

Програм дуусаж байгааг мэдэхийн тулд ApplicationExit үзэгдэлийг захиалах хэрэгтэй. Дараахь жишээнд энэ үзэгдлийг ашиглан програмд хэрэглэгдсэн нөөцүүдийг цэвэрлэж байна:

// Байгуулагч AddressForm() { // ApplicationExit үзэгдэлийг OnAppExit функцээр барих захиалга Application.ApplicationExit += new EventHandler(OnAppExit); } private void OnAppExit(object sender, EventArgs e) { appMutex.Close(); stream.Close(); }

1.3 Clipboard

1.4 Drag and Drop

 

‐68‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 69: C# hicheelin lekts

C# хичээлийн лекцүүд

Контролууд Дэд сэдвүүд:

• Button • TextBox • Label • LinkLabel • ListBox • CheckedListBox • ComboBox • ScrollBar • Агуулагч элементүүд • StatusBar • ProgressBar • PictureBox • TabControl • Toolbar • TreeView

Цонхтой програмд маш олон төрлийн контролууд ашиглагддаг. Зарим контролууд нь нийлмэл, tree view, list view гэх мэт, зарим нь энгийн, button, status bar зэрэг. 2.1 Button Button, RadionButton, CheckBox классууд нь товчлуур ангиллын классд хамаарна. Эдгээр классууд ButtonBase нэртэй нэг классаас удамшсан бөгөөд Windows-н стандарт товчнуудыг дүрслэхэд хэрэглэгддэг. Button ангиллын классуудын нийтлэг шинжүүд нь:

• Дарагдаж болно (click) • Гарчигтай (label)

Button класс нь товчлуур контролыг дүрслэх ба товчлууртай ажиллах үйлдлүүдийг хялбарчилсан үзэгдэл, методуудыг агуулдаг. Button класс нь товчлуурын үзэгдэх байдлыг удирдах пропертинуудыг агуулдаг. Дараахь пропертинуууд хамгийн их хэрэглэгддэг:

• FlatStyle - контролын ирмэг яаж зурагдахыг заана • BackColor - контролын дэвсгэр өнгийг заана • ForeColor – контролын текстийн өнгө • Text - контролд дүрслэгдэх текст

FlatStyle проперти нь дараахь утгуудыг авч болно.

Утга Тайлбар Flat Хавтгай товч Popup Товчлуур ердийн үед хавтгай боловч хулгана дээгүүр нь гүйх үед төвгөр

болно Standart 3 хэмжээст ирмэгтэй товчлуур System Товчлуурын хэв маяг нь үйлдлийн системээр тодорхойлогдоно

‐69‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 70: C# hicheelin lekts

C# хичээлийн лекцүүд

Бусад пропертийн адилаар FlatStyle пропертиг проперти цонхон дээрээс өөрчилж болохоос гадна програмын аргаар өөрчилж болно.

closeButton.FlatStyle = FlatStyle.Flat;

Зарим тохиолдолд товчлуурын гарчигыг солих шаардлага гарна. Жишээлбэл, шинэ цонх нээдэг товчлуур “Нээх” гэсэн гарчигтай байг. Цонх нээгдсэний дараа уг товчлуурын гарчигыг “Хаах” гэж солих нь зүйтэй:

private void ToggleWindow() { if(openButton.Text == "Open Window") { reservationForm = new ReservationForm(); reservationForm.Show(); openButton.Text = "Close Window"; } else { reservationForm.Close(); openButton.Text = "Open Window"; } }

Энэ жишээнд харуулснаар Text пропертийн тусламжтайгаар контролын гарчигийг сольж байна. Бүх цонх, контролууд гарчиг, шошгыг нь өөрчлөх боломж олгох Text пропертитэй байдаг. Товчлуурыг гарны тусламжтайгаар сонгох боломж олгохын тулд гарчигийн нэг тэмдэгтийн өмнө амперсанд (&) хэрэглэнэ:

openButton.Text = "&Close Window";

Амперсанд өмнө нь тавьсан тэмдэгт ба ALT товчны хослолоор тухайн товчлуурыг сонгож болно.

RadioButton контрол нь хэд хэдэн сонголтоос нэгийг нь сонгоход ашиглагддаг. Нэг цонхон дээр олон radio button байх үед хэрэглэгч нэгийг нь сонгоход үлдсэн бусдыг нь сонгоогүй төлөвт оруулдаг. Checked проперти нь товчлуур сонгогдсон эсэхийг мэдэх болон сонгоход ашиглагдана. if(standardRadio.Checked == true) { } standardRadio.Checked = false; CheckBox нь олон сонголтоос хэд хэдэн сонголт хийх боломж олгоно.

‐70‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 71: C# hicheelin lekts

C# хичээлийн лекцүүд

2.2 TextBox TextBox контрол нь текст оруулах, засах үндсэн контрол юм. Зарим чухал пропертиг дараахь хүснэгтэд үзүүлэв. Проперти Тайлбар Text Контролд оруулсан текстийг авах, солих Clear Контрол доторхи текстийг цэвэрлэх PasswordChar Хэрэглэгчийн оруулж байгаа текстийг нууцлах шаардлагатай үед

хэрэглэнэ. Өгөгдсөн тэмдэгтээр хэрэглэгчийн оруулж буй тэмдэгт солигдож бичигдэнэ

Multiline Олон мөр тэмдэгт мөр оруулах боломж олгоно WordWrap Текстийг контролын өргөнтэй тэгшилж цэгцлэнэ AcceptsReturn Энэ проперти true утга авсан үед Enter товч дарж шинэ мөр

оруулахыг зөвшөөрнө. Эсрэг тохиолдолд Enter товч дарсан үед цонхны үндсэн товчлуурыг (default button) сонгох болно

AcceptsTab Энэ проперти true утга авсан үед Tab товч дарж зай авахыг зөвшөөрнө. Эсрэг тохиолдолд Tab товч дарсан үед дараагийн контролыг сонгох болно

BorderStyle Товчлуурын үзэгдэх хэлбэрийг өөрчлөнө 2.3 Label Label контрол нь цонх дээр тодорхойлолт, гарчиг текстүүдийг байрлуулахад хэрэглэнэ. Энэ контрол нь ерөнхийдөө TextBox зэрэг өөрийн гарчиг байхгүй контролуудыг нэрлэх зорилгоор хамт хэрэглэгддэг. 2.4 LinkLabel

LinkLabel нь вэб хуудас дээрх шиг холбоосыг дүрслэнэ. LinkLabel класс нь HTML холбоостой ижил шинжүүдийг агуулсан байдаг. Тухайлбал, холбоосын төлвөөс хамааруулан өөр өнгөөр дүрсэлж болно. Холбоосын өнгийг тодорхойлоход дараахь пропертинуудыг ашиглаж болно:

• ActiveLinkColor – холбоосын сонгогдох үеийн өнгө • DisabledLinkColor - холбоосын идэвхгүй үеийн өнгө • LinkColor - холбоосын ердийн үеийн өнгө • VisitedLinkColor – холбоосын зочилсоны дараахь өнгө

LinkLabel объектоор ашиглагдах өнгүүд нь Properties цонх эсвэл програмын аргаар тогтоогдож болно:

public WebLookForm() { linkLabel.ActiveLinkColor = Color.Lime; linkLabel.DisabledLinkColor = Color.DarkOrange; linkLabel.LinkColor = Color.DarkGreen; linkLabel.VisitedLinkColor = Color.DarkOliveGreen; } Анхны өнгүүд нь LinkColor = Color.Blue, ActiveLinkColor = Color.Red, VisitedLinkColor = Color.Purple байдаг.

‐71‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 72: C# hicheelin lekts

C# хичээлийн лекцүүд

2.5 ListBox

ListBox контрол нь элементүүдийн жагсаалтыг дүрслэнэ. Жагсаалт дахь элементүүдэд хандахад дараахь классуудтай ажилладаг:

• ListBox.ObjectCollection - жагсаалт дахь бүх объектууд • ListBox.SelectedIndex – жагсаалт дахь сонгогдсон элементүүдийн индексүүд • ListBox.SelectedObjectCollection - жагсаалт дахь сонгогдсон элементүүд

Энэ классуудаас хамгийн их хэрэглэгддэг нь ListBox.ObjectCollection юм. Жагсаалт дахь элементүүдийг гарган авахад Items пропериг дараахь байдлаар ашиглана:

private void RemoveItems(ListBox listBox) { ListBox.ObjectCollection items = listBox.Items; if(items.Count != 0) { } }

Ерөнхийдөө, ObjectCollection төрлийн заалт ашиглалгүйгээр шууд Items проперти дээр ажиллах нь хялбар юм:

private void RemoveItems(ListBox listBox){ if(listBox.Items.Count != 0) { } } ListBox.ObjectCollection классын зарим чухал методуудыг дараахь хүснэгтэд үзүүлэв. Метод/проперти Тайлбар Add Жагсаалтад элемент нэмэх Insert Жагсалтад элемент оруулах AddRange Жагсаалтад элементийн олонлог нэмэх RemoveAt Өгөгдсөн индекс дээрх элементийг

устгах Remove Өгөгдсөн элементийг устгах Clear Жагсаалтыг цэвэрлэх ListBox класс нь жагсаалт контролтой ажиллах олон чухал пропертинуудыг агуулна.

• MultiColumn - олон багана элементүүдийг дүрслэх боломж олгоно • ColumnWidth – олон баганатай үед баганын өргөнийг заана • SelectionMode - жагсаалт дахь элементүүд яаж сонгогдохыг заана • Sorted - элементүүдийг автоматаар эрэмбэлнэ • TopIndex – жагсаалт дахь хамгийн дээр харагдах элементийг заана

2.5.1 ListBox-г дахин зуралтаас хамгаалах

‐72‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 73: C# hicheelin lekts

C# хичээлийн лекцүүд

Жагсаалтад элемент нэмэгдэх, хасагдах бүрт контрол дахин зурагдаж байдаг. Олон элементийг нэг үйлдлээр зэрэг нэмэх хамгийн зөв арга нь AddRange методыг ашиглах явдал юм. Гэвч зарим тохиолдолд Add эсвэл Insert-г ашиглан нэг нэгээр нь нэмэх шаардлага байж болно. Энэ үед шаардлагагүй илүү зуралтуудаас зайлсхийхийн тулд BeginUpdate, EndUpdate методуудыг хамтад нь хэрэглэж болно. private void updateListBox() { listBox.BeginUpdate(); foreach(SailboatSlip slip in Marina) { listBox.Items.Add(slip.boat); } listBox.EndUpdate(); }

Энэ жишээнд харуулснаар BeginUpdate метод нь контролын зуралтыг зогсооно. Бүх элементүүд шинэчлэгдэсний дараа EndUpdate дуудагдаж контролыг шинэчилж зурна.

2.5.2 Элемент сонгох Сонгогдсон элементийн индексийг авахад SelectedIndex пропертиг ашиглана. Хэрэв элемент сонгогдоогүй бол -1 утга буцаана. Сонгогдсон элементийг устгах жишээг дараахь кодод үзүүлэв. if(listBox.Items.Count != 0) { int index = listBox.SelectedIndex; if(index != -1) { listBox.Items.RemoveAt(index); } else { MessageBox.Show("You must select an item to remove", "Can't remove item", MessageBoxButtons.OK, MessageBoxIcon.Hand); } } else { MessageBox.Show("The list box is empty", "Nothing to remove", MessageBoxButtons.OK, MessageBoxIcon.Hand); }

Хэрэв контрол хэд хэдэн элемент сонгох боломжтой бол SelectedIndex проперти нь тэдгээрээс аль нэгний индексийг буцаана. Индэкс ашиглалгүйгээр сонгогдсон объектыг шууд гарган авахад SelectedItem пропертиг ашиглаж болно.

Олон элемент сонгох боломжтой ListBox-той ажиллаж байх үед сонгогдсон элементүүдийг авахад SelectedIndices пропертиг ашиглана:

ListBox.SelectedIndexCollection indices = listBox.SelectedIndices; foreach(int index in indices) { Trace.WriteLine("Selected index – " + index.ToString()); }

2.6 CheckedListBox

‐73‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 74: C# hicheelin lekts

C# хичээлийн лекцүүд

CheckedListBox класс нь ListBox классаас удамшсан бөгөөд жагсаалт дотор check box-уудыг хэрэглэх боломж олгодог. CheckedListBox класс нь контролын элементүүдтэй ажиллах дараахь өгөгдлийн цуглуулгуудыг агуулна.

• CheckedListBox.CheckedItemCollection - сонгогдсон элементүүдийн олонлог • CheckedListBox.CheckedIndexCollection - сонгогдсон элементүүдийн

индексүүдийн олонлог

CheckedItemCollection төрлийн олонлогыг гарган авахад CheckedItems пропертиг ашиглана:

CheckedListBox.CheckedItemCollection ci = checkedListBox.CheckedItems;

CheckedIndices проперти нь CheckedIndexCollection олонлогыг гарган авахад хэрэглэгдэнэ:

CheckedListBox.CheckedIndexCollection ci = null; ci = checkedListBox.CheckedIndices;

Тодорхой нэг элемент сонгогдсон эсэхийг мэдэхэд GetItemChecked методыг ашиглана:

bool isChecked = checkedListBox.GetItemChecked(index); 2.6 ComboBox ComboBox контрол нь TextBox ба ListBox контролуудын хослол юм. Тиймээс ComboBox класс нь ListBox ба TextBox классуудын шинжүүдийг удамшин авсан байдаг. ComboBox-н үзэгдэх хэлбэрийг өөрчлөхөд DropDownStyle пропертиг ашиглах ба хэлбэрийг өөрчлөхөд ComboBoxStyle тоочих төрлийн утгуудыг ашигладаг. Утга Тайлбар Simple Жагсаах хэсэг нь үргэлж харагдах бөгөөд хэрэглэгч засах боломжтой DropDown Жагсаах хэсэг нь харагдахгүй бөгөөд хэрэглэгч засах боломжтой DropDownList Жагсаах хэсэг нь харагдахгүй бөгөөд хэрэглэгч засах боломжгүй

Контролын хэлбэрийг ажиллах үед өөрчлөх боломжтой, үүнд дараахь пропертинуудыг ашиглаж болно:

• DropDownWidth - жагсаах хэсгийн өргөнийг заана • DroppedDown - жагсаах хэсэг харагдах эсэхийг заана • Height - энгийн ComboBox-н хувьд өндөрийг заана • MaxDropDownItems - жагсаах хэсэгт харагдах хамгийн их элементийн тоо

2.7 ScrollBar

Өгөгдсөн мужаас их хэмжээтэй мэдээлэл харуулах шаардлагтай үед гүйлгэгч элементийг ашигладаг.

‐74‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 75: C# hicheelin lekts

C# хичээлийн лекцүүд

.NET Framework нь 2 төрлийн гүйлгэгчтэй. HScrollBar класс нь хэвтээ, VScrollBar класс нь босоо гүйлгэгчийг үүсгэхэд хэрэглэгддэг. Эдгээр классууд ScrollBar классаас удамшсан.

Ихэнхи тохиолдолд гүйлгэгчийг үүсгэх шаардлагагүй, олонхи цонхнууд автомат гүйгчтэй байдаг; эдгээр классууд нь ScrollableControl классаас удамшсан байдаг. ScrollableControl классаас шууд бусаар удамшсан классуудын нэг нь Form класс юм. Үндсэн автомат гүйлгэгчийг харуулахын тулд ердөө AutoScroll пропертиг true болгоод л болно:

AutoScroll = true;

AutoScroll-с гадна дараахь пропертинууд гүйлгэгчийн шинжэд нөлөөлнө:

• AutoScrollMargin - Агуулагч цонхны ирмэг ба хүү цүнхны хоорондох шаардлагатай зай. Гүйлгэгч нь энэ нөөц зайг тооцоолон үүсгэгддэг.

• AutoScrollMinSize – Энэ өгөгдсөн хэмжээнээс цонхны хэмжээ бага болох үед гүйлгэгч автоматаар харагдана.

AutoScrollMargin ба AutoScrollMinSize пропертинууд Size төрлийн утгыг авна. Size бүтэц нь тэгш өнцөгтийн хэмжээсийг илэрхийлэхэд Windows Forms классуудад өргөн ашиглагддаг. Size объектыг дараахь байдлаар байгуулж болно:

Size minimumSize = new Size(150, 200);

Анхны төлвөөр, AutoScrollMargin ба AutoScrollMinSize пропертинууд 0 өндөр, өргөн бүхий хэмжээнүүдтэй байдаг. Хэрэв цонхон дээрх контролыг хүрээлээд зай хэрэгтэй бол дараахь байдлаар зааж болно:

AutoScrollMargin = new Size(50, 50);

Дараахь жишээнд цонхны өндөр, өргөн 400-ээс бага болвол гүйлгэгч элемент автоматаар харагдана гэдгийг зааж байна.

AutoScrollMinSize = new Size(400, 400); 2.8 Агуулагч элементүүд

Форм нь хүү контролуудыг агуулдаг элемент юм. Хүү контролуудыг агуулагчид нэмж болно, энэ үед хүүгийн шинжүүд нь агуулагчийнхаа шинжийг дуурайдаг. Жишээлбэл, агуулагчын дэвсгэр өнгө нь хүү контролын дэвсгэр өнгөөр сонгогддог. Хэрэв агуулагч үл үзэгдэх бол хүү контролууд үл үзэгдэнэ, хэрэв агуулагч идэвхгүй бол хүү контролууд мөн идэвхгүй байна.

Form класс нь хамгийн энгийн агуулагч элемент юм. Түүнээс гадна 2 агуулагч байдаг:

• GroupBox – контролуудыг бүлэглэх боломж олгоно, гарчиг байж болно • Panel - контролуудыг бүлэглэх боломж олгоно, гүйгч элементийг дэмжинэ

Эдгээр контролууд нь бусад контролуудыг агуулах, өөр хооронд нь тусгаарлах боломж олгодог.

‐75‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 76: C# hicheelin lekts

C# хичээлийн лекцүүд

Контролуудыг агуулах нийдлэг нэг хэрэглээ бол radio button-уудыг бүлэглэх юм. Ингэснээр нэг цонхон дээр хэд хэдэн бүлэг radio button-ууд байх боломж бүрдэнэ.

Агуулагч дотор контролыг суулгаж байрлуулахад Toolbox цонхноос чирч агуулагч дотор аваачдаг. Өмнө байгаа контролуудын байрлалыг солих бол таслах, оруулах хослолуудыг хэрэглэж болно (Ctrl+X, Ctrl+Y).

2.9 StatusBar

Төлвийн зурвас нь хэрэглэгчид гэдрэг мэдээлэл өгөхөд ашиглагддаг. Тухайлбал, цэсний элементүүдийн тайлбар тодорхойлолт, програмын тухайн үеийн төлөвийг харуулах гэх мэт.

Төлвийн зурвас нь StatusBar классын тусламжтай үүсдэг ба автоматаар цонхны доод хэсэгт байрлана.

Төлвийн зурвасыг хэрэглэхдээ харагдах мужийг хэд хэдэн самбаруудад хуваадаг бөгөөд эдгээр самбарууд нь тодорхой төрлийн мэдээллүүдийг харуулах зорилготой байдаг. StatusBarPanel класс нь нэг самбарыг төлөөлөх ба дараахь пропертитэй.

• Alignment – Хэвтээ чиглэлд байрлалыг заана • AutoSize – Хэмжээ нь автоматаар өөрчлөгдөх эсэхийг илэрхийлнэ • BorderStyle – Самбарын хүрээний хэлбэрийг заана • MinWidth - Самбарын хамгийн доод хэмжээ. AutoSize утга нь None гэж заагдсан

үед энэ пропертигийн утга нь Width –тэй тэнцүү байна • Style – Самбарын зурагдах хэлбэрийг тодорхойлно, үндсэн утга нь

StatusBarPanelStyle.Text байдаг. Өөрийн загвараар самбарыг зурах үед StatusBarPanelStyle.OwnerDraw утгыг оноодог

• Text – Самбарт дүрслэгдэх текст • Width – Самбарын өргөн

2.10 ProgressBar

ProgressBar контрол нь процессийн явцыг хэрэглэгчид харуулахад хэрэглэгддэг. Тухайлбал, файл хуулах зэрэгт ProgressBar контрол дээр явцыг харуулдаг.

‐76‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 77: C# hicheelin lekts

C# хичээлийн лекцүүд

Дараахь метод, пропертинууд нь ProgressBar контролд дүрслэгдэх утгыг өөрчлөхөд ашиглагдана:

• PerformStep - Step пропертид заагдсан алхмаар контролын утгыг өөрчлөнө • Increment - Өгөгдсөн параметерээр контролын утгыг өөрчлөнө • Value - Progress bar-н одоогийн байрлал • Step - Өөрчлөгдөх алхам • Minimum – Доод утга • Maximum – Дээд утга

ProgressBar контрол нь процессийн хэдэн хувьтай явагдаж байгааг харуулдаг учраас доод, дээд утгуудыг хэрэглэдэг. Анхны доод утга нь 0, дээд утга нь 100 байдаг.

Энэ дээд, доод утгуудыг өөрчлөх нэг шаардлага нь тодорхой тооны элементүүдтэй ажиллахад хялбар болгодог. Тухайлбал доод утгыг нь дараахь байдлаар заана:

progressBar.Minimum = 50;

Дээд утгыг нь дараахь байдлаар заана:

progressBar.Maximum = 125;

Ерөнхийдээ заасан алхмаар утгыг ахиулахад PerformStep методыг ашигладаг:

private void timer_Tick(object sender, System.EventArgs e) { progressBar.PerformStep(); if(progressBar.Value == progressBar.Maximum) { // Timer period elapsed.

} }

Дарахь жишээнд ажилбарын явцыг харуулахад Value пропеортиг ашилагасан байна:

progressBar.PerformStep(); progressLabel.Text = string.Format("{0}% complete", progressBar.Value);

2.11 PictureBox

PictureBox контрол нь зурган мэдээллийг харуулахад хэрэглэгдэнэ. Зургийг харуулахад шаардлагатай үйлдүүдийг PictureBox классаар зохион байгуулсан байдаг.

PictureBox классын хамгийн чухал проперти нь Image юм, энэ нь контрол дээр зурагдах зургийг заахад ашиглагдана:

pictureBox.Image = Image.FromFile(@"C:\Windows\winnt256.bmp");

Ихэнхи тохиолдолд зургийн хэмжээ ба PictureBox контролын хэмжээ ялгаатай болдог. SizeMode проперти нь зураг болоод PictureBox контролууд бие биенээсээ хамааран яаж хэмжээгээ өөрчлөхийг заадаг. Энэ проперти нь PictureBoxSizeMode тоочих төрлийн утгууд авах ба дараахь хүснэгтэд харуулав.

‐77‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 78: C# hicheelin lekts

C# хичээлийн лекцүүд

Утга Тайлбар AutoSize Зургийн хэмжээгээр контролын хэмжээ өөрчлөгдөнө CenterImage Зураг контролын төвд голлоно, хэрэв зургийн хэмжээ контролын

хэмжээнээс том бол зургийн ирмэгүүд таслагдана Normal Зураг контролын зүүн, дээд өнцөгт дүрслэгдэнэ. Хэрэв зургийн

хэмжээ контролоос том бол ирмэгүүд нь таслагдана ScretchImage Контролын хэмжээнд тохируулж зургийн хэмжээг өөрчлөнө

2.12 TabControl

Цонх эсвэл диалог цонхон дээрх зайг зөв ашиглахад TabControl-г ашиглах нь тохиромжтой байдаг. TabControl нь нэг талбай дээр олон хуудсуудыг агуулах боломжтой бөгөөд контролын толгой дахь шошгууд дээр дарж хуудсуудыг сонгож болно.

TabPage класс нь нэг хуудсыг дүрслэнэ. TabControl дээр хуудсуудыг нэмэх замаар олон хуудастай болж болно. TabControl нь дараахь метод, пропертиг агуулна.

• Alignment – Хуудсуудыг яаж цэгцлэхийг заана • Appearance – Контролын зурагдах хэлбэрийг заана • Multiline – Олон мөр хуудасууд дүрслэх эсэхийг заана • SelectedIndex – Сонгогдсон хуудсын индекс • SelectedTab – Сонгогдсон хуудас • SizeMode – Хуудсуудын хэмжээ яаж өөрчлөгдөхийг заана

‐78‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 79: C# hicheelin lekts

C# хичээлийн лекцүүд

• TabCount - Хуудсын тоо • TabPages – Хуудаснуудын олонлог

2.13 Toolbar

Хэрэгслийн мөр нь хүссэн командаа цэснээс сонголгүйгээр хулганы нэг даралтаар хялбархан хийх боломж олгодог. Програмд олон дахин хэрэглэгддэг командуудыг хэрэгслийн мөр дээр байрлуулах нь оновчтой.

2.14 TreeView

TreeView контрол нь мод хэлбэрээр өгөгдлийг харуулахад хэрэглэгдэнэ. Мод нь зангилаануудтай байх бөгөөд хамгийн оройн зангилааг үндэс, салаалсан зангилааг хүү гэж хэлдэг. Модтой ажиллахад зарим чухал класс, проперти, методуудыг дараахь хүснэгтэд харуулав.

Класс Метод/проперти Тайлбар TreeNode TreeNode Нэг зангилаа байгуулах TreeView Nodes Хүү зангилаануудын олонлог TreeView SelectedNode Сонгогдсон зангилаа TreeView ExpandAll Бүх зангилааг задлах TreeView CollapseAll Бүх зангилаа хумих TreeView Nodes.Add Зангилаа нэмэх TreeView Nodes.Remove Зангилаа хасах TreeView ShowLines Зангилаануудын хооронд шулуун харагдах

эсэх TreeView ShowPlusMinus Зангилааг задлах, хураах товч харагдах эсэх TreeView BeginUpdate Контрол дээр өөрчлөлт хийхийг хориглоно TreeView EndUpdate Контрол дээр өөрчлөлт хийхийг зөвшөөрнө

Модыг програм ажиллаж байх үед байгуулах тохиолдолд модны үзэгдэлүүдтэй ажиллах шаардлага гарна. Тухайлбал, хэрэглэгч тухайн нэг зангилааг задлах үед түүний хүү зангилаануудыг байгуулж дүүргэж болно. Энэ зорилгод хүрэхийн тулд BeforeExpand үзэгдэл дээр боловсруулалт хийх хэрэгтэй болно:

private void tvRegistry_BeforeExpand(object sender, TreeViewCancelEventArgs e) { tvRegistry.BeginUpdate(); foreach (TreeNode tn in e.Node.Nodes) { AddBranch(tn); }

‐79‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 80: C# hicheelin lekts

C# хичээлийн лекцүүд

tvRegistry.EndUpdate(); }

Дараахь хүснэгтэд модны үзэгдлүүдийг харуулав.

Үзэгдэл Тайлбар AfterCheck Зангилаан дээр check box сонгосны дараа

үүснэ AfterCollapse Зангилаа хураагдсаны дараа үүснэ AfterExpand Зангилаа задарсны дараа үүснэ AfterLabelEdit Зангилааны текст засагдсаны дараа үүснэ AfterSelect Зангилааг сонгосны дараа үүснэ BeforeCheck Зангилаан дээр check box сонгохын өмнө

үүснэ BeforeCollapse Зангилааг хураахын өмнө үүснэ BeforeExpand Зангилааг задлахын өмнө үүснэ BeforeLabelEdit Зангилааны текстийг засахын өмнө үүснэ BeforeSelect Зангилааг сонгохын өмнө үүснэ ItemDrag Мод руу элемент чирэх үед үүснэ

                         

‐80‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 81: C# hicheelin lekts

C# хичээлийн лекцүүд

Лекц№14,15

Үзэгдэл боловсруулалт Дэд сэдвүүд:

• Үзэгдэл барих • Хулганы үзэгдэлүүд • Хулганы заагч • Цэсний үзэгдэлүүд

Бүх контролууд үзэгдэл үүсгэдэг. Үзэгдэл нь бидний сонирхож буй ямар нэг зүйл контрол дээр болжээ гэдгийг мэдээлдэг. Олонхи үзэгдэлүүд хэрэглэгч контролтой харьцах үед үүсдэг. Жишээлбэл, хэрэглэгч товч дарах, текст бичих гэх зэрэгт үзэгдэл үүснэ. Эдгээр үзэгдлийг боловсруулснаар цонхтой програмууд нь хэрэглэгчтэй ойлголцож, хариу үйлдэл хийж байдаг.

Програм нь тухайн үзэгдэлийг барих сонирхлоо үзэгдэл төлөөлөгчөөр дамжуулан бүртгүүлдэг. Програмаар баригдахгүй бусад үзэгдэлүүд нь тухайн контролтой уягдсан классаар боловсруулагддаг. Контролуудын нийтлэг шинжүүд нь суурь классаараа тодорхойлогддог. Жишээлбэл, Control суурь класс нь контролуудад шаардлагатай бүх зүйлсийг агуулсан байна.

Контрол бүр маш олон тооны үзэгдэлүүдийг үүсгэж байдаг. Эдгээрийн олонх нь Control суурь классаар тодорхойлогддог.

Зарим үзэгдлүүд, тухайлбал товч дарахад үүсэх Click үзэгдэл, бараг байнга боловсруулагдаж байдаг. Зарим үзэгдэлүүд дэд контролуудын үзэгдэх байдал, шинжийг өөрчлөх боломж олгодог. Жишээлбэл, цонхны дэвсгэр өнгө, байрлал, хэмжээ зэргийг өөрчлөхөд үзэгдэл үүсэх ба түүнд агуулагдаж байгаа хүү контролууд өөрийнхөө үзэгдэх хэлбэрийг өөрчлөхөд эдгээр үзэгдэлийг ашиглана.

Button контрол нь цонхтой програмуудад хамгийн өргөн ашиглагддаг. Button классаар үүсдэг хамгийн нийтлэг үзэгдэлүүд нь:

• Click - хэрэглэгч контролыг дарах, сонгох зэрэгт үүснэ • Disposed – контролын Dispose метод дуудагдсан үед үүснэ • DoubleClick – хэрэглэгч контрол дээр давхар-даралт хийсэн үед үүснэ • GotFocus – контрол дээр удирдлага очсон үед үүснэ • LostFocus – контролоос удирдлага шилжсэн үед үүснэ • TextChanged - Text проперти өөрчлөгдсөн үед үүснэ • Validated – контролын агуулга шалгагдсан үед үүснэ • Validating – контролын агуулга шалгагдаж байх үед үүснэ

3.1 Үзэгдэл барих

Үзэгдэлийг барих захиалга хийхийн тулд үзэгдэл баригч бичих ба үүнийгээ тусгай нэг үзэгдэлтэй холбож өгдөг. Үзэгдэл барихын тулд хэд хэдэн арга ашиглаж болно. Хамгийн энгийн нэг арга бол үзэгдэлийн төрөлтэй тохирох нэг методыг тодорхойлох, дараа нь түүнийгээ дараахь байдлаар бүртгэх:

‐81‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 82: C# hicheelin lekts

C# хичээлийн лекцүүд

public ButtonForm() {

closeButton.Click += new EventHandler(OnButtonClicked); } private void OnButtonClicked(object sender, EventArgs e) { MessageBox.Show("I've been clicked"); }

Контрол дээр давхар-даралт хийх үед Windows Forms Designer нь тохирох үзэгдэл боловсруулагчийг автоматаар үүсгэж бүртгэдэг. Энэ үед програмын эх кодын цонх автоматаар нээгдэж шинээр үүссэн метод дээр байрладаг.

Контрол нь олон тооны үзэгдэл боловсруулдаг болохоор энэ тохиолдолд хамгийн их хэрэглэгддэг үзэгдэлийг барих үзэгдэл боловсруулагч үүсдэг. Жишээ нь, if you button контрол дээр давхар-даралт хийхэд Click үзэгдэл боловсруулагч үүснэ. Хэрэв text box контрол дээр давхар-даралт хийвэл TextChanged үзэгдэлд зориулсан үзэгдэл баригч үүснэ.

Forms Designer үзэгдэл баригчийг үүсгэхдээ objectname_eventname хэлбэрийн нэршилийг ашигладаг. Тухайлбал, closeButton нэртэй товчны хувьд Click үзэгдэл баригч нь closeButton_Click гэж нэрлэгдэх болно:

private void closeBtn_Click(object sender, System.EventArgs e) { }

Дараа нь энэ методыг бүртгэнэ:

this.closeBtn.Click += new System.EventHandler(this.closeBtn_Click);

Цонх нь ижил төрлийн олон контролуудыг агуулах тохиолдолд бүгдэд нь зориулсан нэг л үзэгдэл баригч байж болно. Үзэгдэл баригчид дамжуулсан sender параметер нь ямар контролоос үзэгдэл үүссэнийг мэдэхэд хэрэглэгддэг:

private void OnClick(object sender, System.EventArgs e) { Button clickedButton = (Button)sender; switch(clickedButton.Name) { case "standardButton": MessageBox.Show("Standard button clicked"); break; case "popupButton": MessageBox.Show("Popup button clicked"); break; case "flatButton": MessageBox.Show("Flat button clicked"); break; default: MessageBox.Show("Unknown button clicked"); break; } }

‐82‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 83: C# hicheelin lekts

C# хичээлийн лекцүүд

Энэ жишээнд standardButton, popupButton, flatButton товчнууд дээрх Click үзэгдэлийг барихад OnClick метод ашиглагдаж байна. OnClick метод нь sender параметерийг Button төрөл рүү хувиргаад, нэрнээс нь хамааруулж ялгаатай мэдэгдэлүүдийг харуулаж байна.

Үзэгдэл боловсруулагчийг бүртгэхийн тулд дараахь байдлаар хийж болно:

EventHandler clickHandler = new EventHandler(OnClick); standardButton.Click += clickHandler; popupButton.Click += clickHandler; flatButton.Click += clickHandler;

Програм ажиллах үед үзэгдэл баригчийг хасахын тулд дараахь байдлаар хэрэглэж болно:

flatButton.Click -= new EventHandler(OnClick); 3.2 Хулганы үзэгдэлүүд Цонхтой програмууд нь ихэнхдээ хулганатай ажилладаг. Хулгана зөөх, дарах зэрэгт үзэгдэл үүсэж програм руу илгээгдэж байдаг. Хулганаар дараахь үзэгдлүүд үүсдэг. Үзэгдэл Тайлбар MouseEnter Хулганы заагч цонх эсвэл контролын мужид орсон MouseHover Хулганы заагч цонхон дээр хөдлөхөө зогссон. Энэ үзэгдэл нь MouseEnter

үзэгдлийн дараа хулганы заагч хөдлөхөө зогсоход үүсдэг MouseLeave Хулганы заагч цонхны мужаас гарсан MouseMove Хулганы заагч шинэ байрлалд шилжсэн MouseWheel Хулганы өнхрүүл хөдөлсөн Дээрх хүснэгт дэх үзэгдлүүдийн олонхи нь EventHandler төрлийнх ба MouseMove, MouseWheel үзэгдэлүүд нь MouseEventHandler төрлийнх юм. MouseMove += new MouseEventHandler(form_MouseMove); private void form_MouseMove(object sender, MouseEventArgs e) { }

Жишээнд харуулснаар MouseEventHandler төрлийн үзэгдэл нь MouseEventArgs параметерийг хүлээж авч байна. MouseEventArgs класс нь дараахь хулганы төлөв болон байрлалын талаар нэмэлт мэдээллээр хангадаг.

• Button - хулганы аль товч дарагдсаныг заана • Clicks – хулганы даралтын тоо • Delta - хулганы өнхрүүлийн эргэлтийн байрлал • X - хулганы заагчын x координат • Y – хулганы заагчын y координат

Ердийн EventArgs параметер дамжуулдаг үзэгдэл боловсруулж байгаа тохиолдолд хулганы координатыг яаж мэдэх вэ? Form класс нь MousePosition пропертитэй бөгөөд энэ нь хулганы байрлаж байгаа координатыг буцаадаг:

private void main_Click(object sender, System.EventArgs e) { Point mousePoint = PointToClient(MousePosition);

‐83‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 84: C# hicheelin lekts

C# хичээлийн лекцүүд

string msg = string.Format("Mouse click at X:{0}, Y:{1}", mousePoint.X, mousePoint.Y); MessageBox.Show(msg); }

MousePosition-н буцаах утга нь xy байрлалыг агуулах Point бүтэц юм. Энэ буцаасан Point бүтэц нь тухайн цонх буюу контролоос хамааралгүй бүтэн дэлгэцийн хувьд хамаатай координат юм. Тиймээс энэ жишээнд байрлалыг цонхны координат руу хувиргахад PointToClient методыг ашиглаж байна.

Дараахь хүснэгт дэх MouseButtons тоочих төрөл нь хулганы товчнуудыг илэрхийлнэ.

Утга Тайлбар None Хулганы товч дарагдаагүй Left Үндсэн (ихэнхдээ зүүн) товч дарагдсан Middle Дунд товч дарагдсан Right Туслах (ихэнхдээ баруун) товч

дарагдсан XButton1 Эхний XButton дарагдсан XButton2 Хоёр дахь XButton дарагдсан

Сүүлийн 2 мөр нь Microsoft IntelliMouse хулганы товчнууд юм, энэ хулгана нь 5 товчтой байдаг ба хуудас хооронд шилжилт хийхэд ашиглагддаг.

Жишээ нь MouseWheel үзэгдлийг барихад дараахь кодыг ашиглаж болно. nameListBox.MouseWheel += new MouseEventHandler(list_MouseWheel); private void list_MouseWheel(object sender, MouseEventArgs e) { }

Хулганы хамгийн өргөн хэрэглээний нэг нь элементийг сонгох юм. Элемент сонгоход оролцох үзэгдлүүд нь MouseDown, MouseUp, Click, DoubleClick юм.

3.3 Хулганы заагч Хэрэглэгчид гэдрэг хариу өгөх аргуудын нэг нь хулганы заагчыг ашиглах юм. Тухайлбал, хулганы заагчын хэлбэрийг өөрчилж хэрэглэгчид түр хүлээх, эсвэл ажилбар дууслаа зэргийг ойлгуулж болно. Хулганы заагчыг өөрчлөхөд цонхны Cursor пропертиг ашигладаг. Cursor = Cursors.WaitCursor;

Cursor пропертиг мөн одоогийн хулганы заагчын хэлбэрийг мэдэхэд хэрэглэж болно.

Cursor oldCursor = Cursor; . . .

Cursor = oldCursor;

Cursors класс нь сдандарт курсорын хэлбэрүүдийг агуулсан байдаг.

‐84‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 85: C# hicheelin lekts

C# хичээлийн лекцүүд

Утга Тайлбар AppStarting Програм эхлэж байгааг илэрхийлсэн хэлбэр Arrow Сум хэлбэрийн заагч Cross Ихэвчлэн зургын хэсгийг сонгох зэрэгт гардаг. Default Үндсэн хэлбэр Hand Ихэвчлэн вэб дээр гипер холбоосыг илэрхийлдэг Help Тусламж HSplit Хэвтээ тусгаарлагчыг илэрхийлнэ IBeam Текст өгөгдөл засварлах үед хэрэглэгдэнэ No Хориглосон заагч. Ихэвчлэн чирэх-тавих үед буруу байрлалд

тавих тохиолдолд хэрэглэгддэг UpArrow Дээшээ сум VSplit Босоо тусгаарлагчыг илэрхийлнэ WaitCursor Хүлээх, систем завгүй байна SizeAll Дөрвөн чиглэлд хэмжээг өөрчлөх SizeNESW Зүүн доош, баруун дээш чиглэлд хэмжээг өөрчлөх SizeNS Дээш, доош чиглэлд хэмжээг өөрчлөх SizeNWSE Зүүн дээш, баруун доош чиглэлд хэмжээг өөрчлөх SizeWE Баруун, зүүн чиглэлд хэмжээг өөрчлөх NoMove2D Хулганы заагчыг хөдөлгөх боломжгүй, харин хэвтээ, босоо

чиглэлд гүйлгэж болно NoMoveHoriz Заагчыг хөдөлгөх боломжгүй, гэхдээ цонхыг хэвтээ чиглэлд

гүйлгэж болно NoMoveVert

Заагчыг хөдөлгөх боломжгүй, гэхдээ цонхыг босоо чиглэлд гүйлгэж болно

PanEast Заагчыг хөдөлгөх боломжгүй, гэхдээ цонхыг зүүн тийш гүйлгэж болно

PanNE Заагчыг хөдөлгөх боломжгүй, гэхдээ цонхыг зүүн дээш гүйлгэж болно

PanNorth Заагчыг хөдөлгөх боломжгүй, гэхдээ цонхыг дээш гүйлгэж болно PanNW Заагчыг хөдөлгөх боломжгүй, гэхдээ цонхыг баруун дээш гүйлгэж

болно PanSE Заагчыг хөдөлгөх боломжгүй, гэхдээ цонхыг зүүн доош гүйлгэж

болно PanSouth Заагчыг хөдөлгөх боломжгүй, гэхдээ цонхыг доош гүйлгэж болно PanSW Заагчыг хөдөлгөх боломжгүй, гэхдээ цонхыг баруун доош

гүйлгэж болно PanWest Заагчыг хөдөлгөх боломжгүй, гэхдээ цонхыг баруун тийш

гүйлгэж болно

Дээрх стандарт заагчын хэлбэрүүдээс гадна өөрийн заагчыг дараахь байдлаар ашиглаж болно.

private void SetSmileyCursor(){

‐85‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 86: C# hicheelin lekts

C# хичээлийн лекцүүд

Cursor _smileyCursor = new Cursor("..\\..\\smiley.cur"); Cursor = _smileyCursor; }

Энд “smiley.cur” файл нь хулганы заагчын дүрсийг агуулсан файл бөгөөд файл систем дээр байрлах ёстой.

3.3 Гарны үзэгдэлүүд

Гарны товчлуур дээр дарахад 3 төрлийн үзэгдэл үүсдэг.

• KeyDown – Товч дарагдсан, товчны төлөв, мэдээллүүд агуулагдана (Ctrl, Shift, and Alt keys).

• KeyPressed – Тэмдэгт товч дарагдсан. Энэ үзэгдэл нь бүх товчны хувьд үүсэхгүй. • KeyUp – Товч салгагдсан.

KeyUp ба KeyDown үзэгдэлүүд нь KeyEventArgs төрлийн параметерүүдтэй байдаг, энэ нь EventArgs классын дэд класс юм. KeyEventArgs нь гарнаас оруулсан өгөгдлийг боловсруулахад хялбар болгосон пропертинуудыг агуулна:

• Alt - Alt товч дарагдсан бол true; эсрэг тохиолдолд false утга буцаана. • Control - Ctrl товч дарагдсан бол true; эсрэг тохиолдолд false утга буцаана. • Handled – Мэдэгдэл боловсруулагдсан эсэх талаар Boolean утга буцаана. • KeyCode – Дарагдсан товчны код, Keys тоочих төрлийн байна. KeyCode нь Shift,

Ctrl, Alt зэрэг товчны хослолуудыг агуулахгүй. • KeyData – Дарагдсан товчны код, Alt, Shift, Ctrl зэрэг хослол товчнууд дарагдсан

бол цуг агуулна. • KeyValue - KeyData –ийн бүхэл тоон хувилбар. • Modifiers - Alt, Shift, Ctrl товчнууд дарагдсан үед кодыг нь агуулна. • Shift - Shift товч дарагдсан бол true; эсрэг тохиолдолд false утга буцаана.

Alt, Control, Shift зэрэг товчнууд нь бусад товчнуудын утгыг өөрчлөх үүрэгтэй байдаг. Ийм хувиргагч товч дарагдсан эсэхийг таних нэг арга нь дараахь кодод харуулсан байна:

if(e.KeyCode == Keys.Q) { if(e.Shift == true) { } if(e.Control == true){ } }

Өөр нэг арга нь Modifiers пропертиг ашиглах, энэ проперти нь хэд хэдэн хувиргагч товчлуур дарагдсан үед хэд хэдэн утга агуулна. Яг ямар товчнууд дарагдсан эсэхийг мэдэхийн тулд дараахь кодыг ашиглаж болно:

if(e.KeyCode == Keys.B) { if(e.Modifiers == (Keys.Control │ Keys.Shift) { }

‐86‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 87: C# hicheelin lekts

C# хичээлийн лекцүүд

}

Хэрэв олон хувиргагч товчны хослол шалгах гэж байгаа бол Modifiers пропертиг ашиглана, хэрэв нэг хувиргагч товчны төлөв шалгах бол KeyEventArgs классаас тохирох нэг пропертиг ашиглах хэрэгтэй.

KeyPress үзэгдэл нь KeyDown ба KeyUp үзэгдэлүүдийн хооронд үүсдэг үзэгдэл юм. KeyDown ба KeyUp үзэгдэлүүдтэй адилгүй нь KeyPress үзэгдэл KeyPressEventArgs төрлийн параметертэй байдаг. KeyPressEventArgs класс нь товчны код, хувиргагч товчнуудын тухай мэдээлэл өгөхгүй бөгөөд дараахь пропертитэй:

• Handled - Үзэгдэл боловсруулагдсан эсэх мэдээлэл • KeyChar – Дарагдсан товчны тэмдэгт утга

KeyPress үзэгдэл нь энгийн текст оруулах үед тохиромжтой юм. KeyDown ба KeyUp үзэгдэлүүд нь функциональ болон удирдах товчнуудыг боловсруулахад тохиромжтой.

Keys тоочих төрөл нь гарнаас үүсэх бүх товчлуурын кодуудыг агуулдаг. Нийтдээ 183 утгыг агуулах бөгөөд энд бүгдийг тоочих боломжгүй учраас зарим жишээг харуулав.

Утга Тайлбар A A тэмдэгт F5 F5 удирдах товч D9 9 цифр LShiftKey Зүүн Shift товч

3.3.1 Фокус

Хугацааны нэг эгшинд бүх програм, бүх контролд гарнаас өгөгдөл оруулах нь боломжгүй юм. Гарнаас өгөгдөл оруулахын тулд тухайн цонх эсвэл контрол дээр удирдлага (focus) шилжсэн байх ёстой. Жишээ нь, text box контрол дээр фокус шилжсэн үед босоо зураас (|) харагдаж тэмдэгт оруулах боломжтой болдог.

Фокусыг өгөгдсөн контрол руу шилжүүлэхийн тулд Focus методыг ашигладаг. Мөн Focus метод нь тухайн контрол дээр фокус байрласан бол true, эсрэг тохиолдолд false утга буцаадаг.

if(nameTextBox.Focus() == false) { Trace.WriteLine("Couldn't set focus to text box"); }

Control класс нь фокусыг удирдах дараахт пропертиг агуулдаг:

• CanFocus – Контрол дээр фокус шилжих боломжтой бол true, эсрэг тохиолдолд false утга буцаана

• ContainsFocus – Тухайн контрол эсвэл түүний хүү контрол дээр фокус байрласан бол true, эсрэг тохиолдолд false утга буцаана

• Focused – Контрол дээр фокус байрласан бол true, эсрэг тохиолдолд false утга буцаана

‐87‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 88: C# hicheelin lekts

C# хичээлийн лекцүүд

Контрол нь идэвхтэй бөгөөд хамийн дээд түвшинд байрлах үед фокус авах боломжтой байдаг. Фокус авах боломжтой эсэхийг CanFocus проперти ашиглан дараахь байдлаар шалгаж болно:

if(nameTextBox.CanFocus) { }

ContainsFocus проперти нь тухайн контрол эсвэл түүний хүү контролуудаас фокус авсан эсэхийг мэдэхэд чухал байдаг:

if(this.ContainsFocus) { }

Фокусыг шалгахын оронд дараахь үзэгдэлүүдийг ашиглаж болно:

• Enter – Контрол эсвэл түүний хүү контролуудаас аль нэг нь фокус авсан үед үүснэ

• Leave - Контрол эсвэл түүний хүү контролуудын аль нэгээс фокус гарсан үед үүснэ

Enter ба Leave үзэгдэлүүдийг хэрэглэгчийн интерфэйсийг сайжруулахад ашиглаж болно, жишээлбэл, контрол фокус авсан үед түүнтэй холбоотой тусламж мэдээллийг харуулж болно:

private void nameTextBox_Enter(object sender, System.EventArgs e) { helpLabel.Text = "Enter the user's first and last name"; } private void nameTextBox_Leave(object sender, System.EventArgs e) { helpLabel.Text = ""; }

3.4 Цэсний үзэгдэлүүд

Цэс нь цонхтой програмуудад нийтлэг хэрэглэгддэг хэрэглэгчийн интерфэйс юм. Цэс нь мод хэлбэрийн шаталсан холбоо хамааралтай ба ихэвчлэн тодорхой тооны оройн элементүүдийг агуулсан байдаг. Оройн элементүүд нь задрах дэд цэсүүдийг агуулсан байдаг, дэд цэсүүд нь мөн өөртөө дэд цэсүүдийг агуулж болно.

Цэс бүхий хэрэглэгчийн интерфэйс үүсгэхдээ дараахь дүрмүүдийг баримтлах хэрэгтэй.

• Цэсний элемент нь туслах тэмдэгттэй байх хэрэгтэй – энэ тэмдэгт нь цэсний элементийн нэг хэсэг бөгөөд Alt товчтой хамтран тухайн элементийг сонгоход хэрэглэгдэнэ. Жишээлбэл, Ихэвчлэн File цэс нь F тэмдэгттэй холбогдсон байдаг ба Alt+F товчны хослолоор File цэсийг дуудаж болдог.

• Дэд цэс агуулдаггүй шууд команд дууддаг цэсний элемент нь нэрнийхээ ард анхааруулсан тэмдэгттэй байх хэрэгтэй. Энэ нь тухайн цэсийг сонгосон үед шууд команд дуудагдах болно гэдгийг хэрэглэгчид анхааруулна.

• Диалог цонх зэрэг хэрэглэгчээс нэмэлт мэдээлэл шаардах цонх харуулах цэс нь нэрнийхээ ард (...) –тэй байх нь зүйтэй.

Хэрэглэгч цэснээс сонголт хийх үед дараахь үзэгдлүүд үүснэ.

‐88‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 89: C# hicheelin lekts

C# хичээлийн лекцүүд

• Popup – Дэд цэс задрах үед үүснэ. Энэ үзэгдэл нь дэд цэсний элементүүдийг динамикаар өөрчлөх боломж олгоно.

• Select – Цэсний элемент сонгогдсон, гэхдээ дарагдаагүй. Энэ үзэгдэл нь сонгох гэж буй цэсний талаар status bar зэрэг контролууд дээр туслах мэдээлэл харуулахад чухал байдаг.

• Click – Хэрэглэгч цэсний элементийг сонгосон. Энэ нь цэстэй холбоотой үзэгдэлүүдээс хамгийн их хэрэглэгддэг бөгөөд энэ үзэгдэлийн цаана тодорхой үйлдлүүдийг хийж байдаг.

Эдгээр цэсний үзэгдэлүүд нь тодорхой нэг цэс сонгогдсон эсэх талаар мэдээлнэ, харин сонголтыг цуцалсан талаар талаар ямар нэг зүйл хэлэхгүй. Form класс нь цэс задраад цуцлагдсан тухай мэдээлэл өгөх дараахь үзэгдэлүүдийг агуулна:

• MenuStart – Цэс дээр фокус очих үед үүснэ • MenuComplete – Цэснээс фокус гарах үед үүснэ

MenuStart үзэгдэл нь ерөнхийдөө хэрэглэгчийн интерфэйс элементүүдийг өөрчлөхөд хэрэглэгддэг. Тухайлбал, цэс сонгогдсон үед тодорхой контролуудыг идэвхгүй болгох гэх мэт.

MenuComplete үзэгдэл нь MenuStart үзэгдэлээр хийгдсэн үйлдлүүдийг буцаахад хэрэглэгддэг. Энэ үзэгдэл нь хэрэглэгч цэсийг сонгож дууссаны дараа эсвэл сонголтыг цуцлаад өөр объект сонгосон үед үүснэ.

                       

‐89‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 90: C# hicheelin lekts

C# хичээлийн лекцүүд

Лекц№16

Цонхны график Дэд сэдвүүд:

• Цонхны геометр • Зуралт хийх

4.1 Цонхны геометр

GDI+ нь цонхтой програмуудад зориулсан график дүрсүүдийг зурах шинэ хэрэгсэл юм. GDI+ нь Windows-н хуучны хувилбаруудад хэрэглэгддэг Graphical Device Interface (GDI)-г өргөтгөсөн шинэ хувилбар юм.

Цонхон дээр шууд зуралт хийхэд Graphics классын методуудыг ашигладаг. Мөн энэ классыг ашиглан цонхны горим, дэлгэцийн боломжуудын тухай мэдээллүүдийг авах боломжтой.

Дүрсүүд болон тэдгээрийн байрлал, хэмжээг тодорхойлоход Point, Size, Rectangle зэрэг бүтцүүдийг өргөн ашигладаг.

4.1.1 Цэгийн Байрлал

Point бүтэц нь 2 хэмжээст цонхны гадаргуу дээр байрлал тодорхойлох, шулуун, тэгш өнцөгт болон бусад дүрсүүдийг тодорхойлоход өргөн ашиглагддаг. Point нь дараахь 2 проперти агуулна.

• X – хэвтээ чиглэлт x координат • Y – босоо чиглэлд y координат

Point бүтцийн үндсэн байгуулагч нь (0,0) утгатай хоосон цэгийг үүсгэдэг. Цэг нь хоосон эсэхийг IsEmpty пропертигээр шалгаж болно. if(pt.IsEmpty) { // pt is an empty Point structure. }

Pointбүтэц үүсгэх хамгийн энгийн арга нь xy координатаар нь үүсгэх юм:

int x = 10; int y = 20; Point pt = new Point(x, y);

PointF бүтэц нь Point бүтэцтэй төстэй бөгөөд ялгаа нь кооринатууд нь илүү сайн нарийвчлалтай бодит тоон утгуудаар илэрхийлэгддэг.

float x = 22.4f; float y = 17.8f; PointF pt = new PointF(x, y);

PointF төрлөөс Point төрөл рүү хөрвүүлэхэд Point бүтцийн дараахь статик методуудыг ашигладаг:

‐90‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 91: C# hicheelin lekts

C# хичээлийн лекцүүд

• Ceiling - координатыг дараагийн их утгатай бүхэл тоо руу тоймлож хөрвүүлнэ • Round – координатыг ойролцоо бүхэл тоо руу тоймлож хөрвүүлнэ • Truncate – координатыг ойрын бага утгатай бүхэл тоо руу тоймлож хөрвүүлнэ

Point төрлөөс PointF төрөл рүү хөрвүүлэхэд далд хөрвүүлэлт автоматаар хийгдэнэ.

4.1.2 Дүрсийн хэмжээ

Size бүтэц нь цонх, контрол болон бусад тэгш өнцөгт мужуудын хэмжээг заахад ашиглагддаг. Size бүтэц нь 2 байгуулагчтай: эхнийх нь Point утгыг хүлээн авна:

Point pt; Size mySize = new Size(pt);

Энэ байгуулагч нь Point бүтцийн x координатыг урт, y координатыг өндөр болгон авдаг.

Дараагийн байгуулагч нь урт, өндөрийг бүхэл тоон утгаар хүлээн авна:

int width = 20; int height = 10; Point pt = new Point(width, height);

Size бүтэц нь урт, өндөрийг илэрхийлэх Width ба Height пропертитэй.

SizeF бүтэц нь Size бүтэцтэй төстэй боловч бодит тоон утгуудаар хэмжээг илэрхийлдэг.

4.1.3 Тэгш өнцөгт

Rectangle бүтэц нь тэгш өнцөгтийн хэмжээ, байрлалыг заахад хэрэглэгдэнэ, энэ нь цонх, контрол зэргийг зурахад ашиглагддаг уламжлалт бүтэц юм. Rectangle бүтэц нь зүүн дээд өнцгийн байрлалыг заах Point бүтэц, тэгш өнцөгтийн урт, өндөрийг илэрхийлэх Size бүтэцийн хослол юм.

Rectangle бүтэц үүсгэхэд 2 байгуулагч байна. Эхний байгуулагч нь Point ба Size бүтцийг параметр болгон авдаг:

Size mySize = new Size(200, 300); Point startPoint = new Point(10, 10); Rectangle myRect = new Rectangle(startPoint, mySize);

Хоёрдахь хувилбар нь тэгш өнцөгтийн хүрээг тодорхойлох 4 бүхэл тоон утгыг авдаг:

int left = 10; int top = 10; int width = 200; int height = 300; Rectangle myRect = new Rectangle(left, top, width, height);

Rectangle бүтэц нь дараахь пропертитэй:

• Left • Right • Top

‐91‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 92: C# hicheelin lekts

C# хичээлийн лекцүүд

• Bottom • Width • Height

RectangleF нь Rectangle бүтэцтэй төстэй бөгөөд бодит тоон утгуудаар хэмжээс нь илэрхийлэгддэг.

4.2 Зуралт хийх

Цонхтой програмуудын хувьд Paint үзэгдэлийн цаана зуралт явагддаг. Өмнөх жишээнүүдэд үзэж байсан бүх контролууд нь Paint үзэгдэлийг боловсруулж өөр өөрсдийн зуралтийг далд хийж байдаг.

Paint үзэгдэл нь PaintEventHandler төлөөлөгчөөр боловсруулагддаг:

Paint += new PaintEventHandler(this.Form_Paint); private void Form_Paint(object sender, System.Windows.Forms.PaintEventArgs e) { }

PaintEventHandler төлөөлөгч нь PaintEventArgs параметрийг хүлээж авдаг, энэ параметр нь дараахь 2 чухал пропертиг агуулдаг:

• Graphics – Зуралт хийх Graphics төрлийн объектыг буцаана • ClipRectangle - Зуралт хийгдэх тэгш өнцөгт муж

Graphics класс нь шулуун, текст болон дүрсүүдийг зурахад зориулагдсан олон тооны методуудыг агуулна.

4.2.1 Текст зурах

Консоль програмын хувьд Console.Write, Console.WriteLine методуудыг ашиглаад текстийг хэвлэдэг бол цонхтой програмын хувьд илүү олон мэдээлэл шаарддаг.

Цонхон дээр текст зурахад DrawString методыг ашигладаг бөгөөд энэ методын 6 хувилбар байдаг. Эхний хэлбэр нь хамгийн энгийн бөгөөд текстийн байрлалыг заахад PointF бүтцийг ашигладаг:

PointF textPoint = new PointF(12.0f, 12.0f); e.Graphics.DrawString("Text location specified by a PointF value", Font, SystemBrushes.WindowText, textPoint);

Дараагийн хувилбар нь бодит тоон утгаар байрлалыг нь заах боломжтой:

e.Graphics.DrawString("Text location specified by float values", Font, SystemBrushes.WindowText, 12.0f, 12.0f);

‐92‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа

Page 93: C# hicheelin lekts

C# хичээлийн лекцүүд

DrawString методын дээрх хоёр хувилбар дээр урт текст зурах үед гарах асуудал гарна. Дээрх методууд нь нэг мөр текстийг зурдаг бөгөөд текстийн урт контролын эсвэл цонхны мужаас хэтэрсэн үед ирмэг дээгүүр хэтрэн зуралт хийдэг.

Гурав дахь хувилбар нь RectangleF төрлийн утга дамжуулан текстийн зурагдах мужийг хязгаарлаж, текстийг тухайн мужид багтаан зурдаг:

string crispinSpeech = "We few, we happy few, we band of brothers. " + "For he today that sheds his blood with me " + "shall be my brother, be he ne'er so vile, " + "this day shall gentle his condition. " + "And gentlemen in England now abed " + "shall think themselves accursed they were not here, " + "and hold their manhoods cheap whiles any speaks " + "that fought with us upon Saint Crispin's day. "; RectangleF boundingRect = new RectangleF(12.0f, 100.0f, 180.0f, 180.0f); e.Graphics.DrawString(crispinSpeech, Font, SystemBrushes.WindowText, boundingRect);

Үлдсэн гурван хувилбар нь өмнөх хувилбаруудтай төстэй бөгөөд ялгаа нь StringFormat төрлийн параметрийг авдаг. StringFormat нь текстийг яаж байрлуулахыг заана. StringFormatFlags тоочих төрөл нь байрлуулах утгуудыг агуулна.

Утга Тайлбар DirectionRightToLeft Баруунаасаа зүүн тийш зурагдана DirectionVertical Босоо чиглэлд зурагдана DisplayFormatControl Тэмдэгтийг дүрслэх тусгай формат FitBlackBox LineLimit MeasureTrailingSpaces NoClip NoFontFallback NoWrap

 

‐93‐      Боловсруулсан:

ММЗТ-н багш Б.Болормаа