# .NET Uzbekistan

Microsoft .NET platformasi bo'yicha O'zbekistonda ilk dokumentatsiya

### Nega tafakkur qilmaymiz?

Assalomu aleykum qadrli dasturchilar! Bilaszmi men o'z tajribam davomida shuni o'rgandimki, tafakkur degan tushunchaning o'rni dasturlashda ham juda katta ekan. Bu narsaning dasturchiga kerakli ekanini isbotlarini ham keltirishim mumkin. "Dasturlashda tafakkur" jumlasini nega ishlatdim? Bu o'z ichiga nimalarni oladi?

Ko'p dasturchilarni bilaman) Dasturlashdan boshqa narsani bilmedi!!! (Shunaqasi ham bo'larkanmi? :) Qisqa qilaman... Kompyuter strukturasini o'rganib chiqing. Chuqur emas, shunchaki tuzilishini o'rganishni maslahat beraman. Sababi Ma'lumotlar qanday borib keladi? Protsessor qanday ishlaydi? Ushbu dasturni ishga tushishi uchun mening kompyuterim talablari qanday? Pixelli va Vectorli grafika....?

Hullas, gapni indallosi - Shu savollarga javob bera oladigan bo'lsangiz, sizdan juda zo'r dasturchi chiqishini 90% kafolatlayman (Boshqa talablar ham bor, erkalanib ketmang...). Ushbu jarayonga tashxis qo'yish uchun qisqa ertak aytib beraman.

{% hint style="info" %}
Bir bor ekan, bir yo'q ekan, bitta chala dasturchi bor ekan. O'zicha juda kuchli emishda endi...:). Kunlarning birida u Java va .NET (C#) ni solishtirish niyatida, ikkalasida ham bir xil natija beruvchi kod yozmoqchi bo'libdi. Demak, bizning qahramon birinchi bo'lib "IntelliJ IDEA" (Javada ishlash uchun eng zo'r muhit desak bolaveradi) ni ishga tushiribdi. O'sha o'zi xohlagan kichik proyektni tugatibdi... Keyn "Visual Studio" (.NET da ishlovchi eng zor muhit hozirda) ni ishga tushiribdi. Endigi navbat C# ga kelibdida... O'sha proyektni C# da boshlabdi... Qarasa asabi o'ynayapti. Negaki kompyuter qotayotgan edi. Cho'ta kompyuter rosa qiynalyapti, bechara CPU (protsessor) dan chiqayotgan issiqlikka tuxum pishirsa bo'ladi...:) Natijada bizning shef o'z kompyuterini jahl ustida bir urdi... Shunday urdi keyboard (klaviatura) ga, shunday urdi.... bir nechta klavishlar ishlame qoldi.
{% endhint %}

![Endi nima qilaman?](https://user-images.githubusercontent.com/91861166/215678965-56826622-830d-4c08-84ac-803599cec695.jpg)

Bizning hikoya Abdukarim Mirzayevnikiga o'xshagan zo'r emasda... Lekin hissasi zo'r. Agarda bizning dasturchi kompyuterni RAM i qanday ishlashini bilganida edi. Anavi kompyuterni dardini tushungan bo'lar edi. Sababi, RAM (tezkor xotira) to'lib qolgan. chunki 4GB edi xolos, CPU esa AMD edi. Buni tushunganlar tushunadi qanday og'ir dard ekanligini? Visual Studio va IntelliJ ni ishga tushirganda OZU ni to'ldirgan, bundau ikkita gigant windows dasturlari ishga tushganda, yana nima kutlishi mumkin. O'ylash kerak, to'xta.... Ushbu dasturlar talablari meni kompyuterimni to'gri kelmaydi, tim bo li ikkita katta dastur... Agarda shu narsaga e'tibor berganda, nimadir bo'lishini oldini olgan bo'lar edi.

Bu qolganlar uchun oddiy holdek tuyilishi mumkin. Lekin bu jiddiy muammo. Hammasi bilimsizlikdan kelib chiqadi. Gapni qisqa qilaman, komp qanday ishlashini tushunishingiz kerak do'stlarim. Bu o'sha peshanasida xoli bor Muhammadkarim To'xtaboyev ni gapi.... Xaxaxaaa

![](/files/-MYsrVORCGzhmSHVr8zg)


# C# / .NET


# .NET ga xush kelibsiz

Kross platforma, open source va dasturchilar uchun IOT, Mobile, Desktop, Web, Game turdagi maxsulotlar ishlab chiqish uchun bepul platforma

Assalomu alaykum mening qadrdonlarim! Sizlarga .NET bo'yicha bilim berishni bugundan niyat qildim. Agar sizlarni Microsoft kompaniyasi tomonidan yaratilgan maxsulotlar qiziqtirsa va o'sha maxsulotlar orqali o'z maxsulotingizni ishlab chiqmoqchi bo'lsangiz, siz hozir yo'nalish tanlashda adashmadingiz! .NET GA XUSH KELIBSIZ.

![Qaysi yo'nalishdan ketmoqchisiz?](/files/-MWsNeS0VsvQFao5mRur)

### .NET tillari

Siz .NET ilovalarini ishlab chiqish uchun C#, F#, Visual Basic tillaridan foydalanishingiz mumkin.

### .NET ni yuklash

Barcharga ma'lumki, .NET frameworklarining 3 turi hozirda faoliyatda. ".NET Framework", ".NET Core", ".NET5". Uchchala frameworkda ham SDK va Runtime bor. .NET SDK - dasturning qurilishi va ishga tushishini taminlaydi. .NET Runtime - Dasturning ishga tushishini taminlaydi xolos. Aytmoqchimanki, SDK o'zining ichiga Runtime ni ham oladi. Agar o'zining ichiga olsa nega kerak?

Barchamizga ma'lum .NET platformasida yozilgan ilovalarni ishga tushirish uchun .NET Runtime lari kerak bo'ladi. Bu sizga C++ emas. Istalgan kompyuterda ishga tushib ketaveradigan. Ya'ni Windows tizimi kompyuterga yangi o'rnatilgan paytda C++ Runtime lari bo'ladi. Shuning uchun C++ da yozilgan ilovalarni ishga tushirishda xech qanday so'rov bo'lmaydi. Mana endi sekin sekin Windowsning yangi versiyalarida .NET frameworklari ko'zga ko'rinyapti.

{% hint style="info" %}
Aytaylik men dasturchiman va .NET (C#) da biror ilova ishlab chiqdim, yoki Telegramga o'xshagan dastur... xullas nima farqi bor.... Keyin uni do'stimni kompyuteriga o'tkazdim. Do'stim esa dasturchi emas. Shu bilan birgalikda .NET SDK ham o'rnatmaydi, SDK dasturchiga kerak xolosda. Chunki yozgan kodini build qilib berishi kerak bo'ladi. Oddiy odam esa kod yozmaydi. Dasturchi bo'lmagan oddiy odamga .NET Runtime beriladi. Yani Runtime dasturini kompyuteriga install qilgandan keyin, bizning dasturni ochishda muammo bo'lmaydi. Aks holda .NET Frameworkini o'rnat didi.
{% endhint %}

Demak SDK va Runtime farqini tushinib oldingiz.

Keling, ushbu frameworklarning farqlarini ko'rib chiqamiz.

{% tabs %}
{% tab title=".NET Framework" %}
Ushbu framework orqali .NET ilovarini faqat windows operatsion tizimi uchun ishlab chiqish mumkin. (Tolka windows :). .NET Frameworklarining turli versiyalari bor va bular 4.7.2 gacha yetib kelgan.\
\
.NET Framework Dev Pack (SDK): <https://dotnet.microsoft.com/download/dotnet-framework/thank-you/net48-developer-pack-offline-installer>\
.NET Framework Runtime: <https://dotnet.microsoft.com/download/dotnet-framework/thank-you/net48-web-installer>
{% endtab %}

{% tab title=".NET Core" %}
.NET trendga chiqayotgan bir paytda, Java va .NET dasturchilari o'rtasida muzokaralar kelib chiqdi, chunki C# bu Microsoftning Javasi. Bu yerda muammo nima edi? C# orqali faqat Windows OS ga ilova yozish mumkin edi. Java da edi muammosiz barchasiga. Ushbu muammolardan keyin Microsoft ham o'zining cross platformali frameworkini ishlab chiqdi. Uning nomi .NET Core edi. Bu framework orqali Windows, Linux, MacOS, Docker (Docker haqida [bu yerdan](https://www.youtube.com/watch?v=trW0gihZ78E\&list=PL_WK6W0Gn1I4jcUIwAUkcLM76k08Bqi2K) o'rganasiz) OS lariga ham ilovalar yaratish imkoni bor edi. Keyinchalik ko'p dasturchilar .NET Core ga o'tishdi. Qoladiganlari qoldi ham... Chunki Ko'p loyihalar .NET Frameworkda ko'tarilgan edi. Uni .NET Core ga olish da esa muammolarga duch kelish mumkin edi. Agar faqat Windows da ish qiluvchilar bo'lsa bundan muammo emasdi lekin... Aytganimdek, hozirda ham .NET Frameworkda ish qiladiganlar bor.

.NET Core SDK: <https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-3.1.408-windows-x64-installer>\
.NET Core Runtime: <https://dotnet.microsoft.com/download/dotnet/3.1/runtime>\\
{% endtab %}

{% tab title=".NET 5" %}
Endi deyarli loyihalarda muammolar yo'q edi, yagona muammoni qo'shmaganda. Ko'p dasturchilar .NET Core da ishlaydi, qolganlari esa .NET Frameworkda. Qaysidir Service lar yoki paket, kutubxonalar .NET Frameworkda yozilgan edi, ularning ko'pi hali .NET Core ga olinmagan edi. Aytmoqchimanki, katta loyihalarni ishlab chiqishda, kimdir qaysidir service ni .NET Frameworkda yozgan, masalan tayyor kutubxonani. Asosiy loyiha esa .NET Core da ko'tarilgan. Endi anavi kutubxonadan foydalanishda ozgina muammo kelib chiqishi mumkin. Chunki ularning qurilishi bir biriga to'g'ri kelmaydi. 1 ta gina yo'l bor edi. .NET Framework loyihasini .NET Core ga konvertatsiya qilish kerak edi. Qilishni ham yo'lini topishdi ammo barbr optimal emasdi. Keyin ular .NET5 ni ishlab chiqishga kirishishdi. Bu uchun tashqaridan ko'plab kontributerlar (ko'ngilli dasturchilar) ham jalb qilingan edi. Hozirda hali ham uning ustida ish olib borilmoqda. Bu frameworkni oddiy qilib tushintirganda .NET Framework + .NET Core ham deyish mumkin. Ya'ni endi ishlar yana ham standartlashdi. .NET Standart edi. .NET 5 da loyiha ko'tarilsa, istalgan frameworkdagi service larni qabul qilad oladi. Kimdir Core da yoki Frameworkda yozsa kutubxonalarni. .NET5 orqali ularni bemalol import qilib ishlatish mumkin edi. Qo'rqmasdan ayta olaman, hozirda barcha NET 5 ga o'tyapti, ba'zi injiqlarni hisobga olmaganda.

![](/files/-MYtbcP0oku3Pb8Bopm4)

.NET SDK: <https://dotnet.microsoft.com/download/dotnet/thank-you/sdk-5.0.202-windows-x64-installer>\
.NET Runtime: <https://dotnet.microsoft.com/download/dotnet/5.0/runtime>
{% endtab %}
{% endtabs %}

Keling quruq SDK ni o'zi orqali "Hello World" ni ekranga chiqarishni o'rganamiz.

### Hello World! (Hech qanday muhitsiz)

Hamma tilda ishlash uchun muhit kerak bo'ladi. Huddi avvalgi mavzuda gapirgan Visual Studio yoki IntelliJ IDEA lar kabi. Aslida kodlar qanday quriladi. Amalga oshishi qanday bo'ladi? Qaysidir ma'noda bu jarayonni ham "Dasturlashda tafakkur" tushunchasiga misol qilsak bo'laveradi. Shunchi men o'zimni boshimdan o'tkazganman. Har xil savollar bo'ladida...\
\- Loyihamga nuget (paketlar menejeri) dan paket o'rnata olmayapman?\
\- Dasturni kompilatsiya qilib bo'lmayapti?\
\- Visual Studio dasturi meni kompyterimga tushmayapti?\
Shunday savollarni ko'pini o'quvchilarimdan eshitganman. Ushbu gap so'zlardan keyin "Dasturlashda tafakkur" nomli qizg'in bir tushunchani kiritdim (o'zimni lug'atimga :). Agar bizning kodlarimiz qay tarzda build (qurilish) bo'lishini bilganimizda, bizga Visual Studio kerak emas edi. Kerak bo'lsa o'zimiz Visual Studio yaratgan bo'lardik. Qachonlardir C++ uchun yangi muhit qilgan edim C# orqali. Bu bilan nima demoqchiman? Keling "Hello World" natijani olish uchun visual studiodan kechib turamiz bir gal.... Demak boshladik.

### .NET SDK ni o'rnatamiz.

Avvalo .NET SDK ni yuklab olishimiz kerak bo'ladi [bu yerdan](https://dotnet.microsoft.com/en-us/download).

Visual Studio esa siz va .NET SDK o'rtasidagi vositachi xolos. Keling Visual Studioni ishini o'zimiz ham qilib ko'ramiz, vaziyatni baholash uchun. Hullas SDK ni yukladik, endi uni install qilamiz. Menimcha qiyinchilik tug'diymaydi. Agar xatolik bersa, demak avval .NET ning boshqa versiyasi ustanovka qilingan bo'ladi, o'shani o'chirib tashlab keyn buni install qlish kerak, agar lozim topsangiz. Menimcha boshqa xatolik yuz bermaydi. SDK o'rnaganini tekshirish uchun CMD ni ochamiz. buning uchun WIN+R klavishlari bosiladi va CMD deb yoziladi.

![Vipolnit](/files/-MYsxSqNs-JkY5307-2j)

CMD ga "dotnet" deb yozish kifoya. Agar .NET SDK o'rnatilgan bo'lsa, ushbu kalit so'zni taniydi, aks holda bu so'z notanish deb inglizcha yoki ruscha gap chiqadi.

![Anaa dotnet ni tanigani uchun shu narsalar chiqdi](/files/-MYsxrurOeI8lrB4ac6-)

### Error berib qolishi mumkinmi?

{% hint style="info" %}
Albatta error ham berishi mumkin, faqat bir holatda.\
*'dotnet' is not recognized as an internal or external command*\
\_\_Yoki dotnet SDK install bo'lmagan bo'ladi, yoki CMD ni avvalroq ochib olgansiz (SDK install bolishidan avval). Muammoni hal qlish uchun CMD ni qayta ishga tushirib yuborish talab etiladi.
{% endhint %}

### Yangi loyiha yaratish

Yangi loyiha yaratish uchun CMD ni orqali ushbu buyruqni ishga tushiring:

```bash
> dotnet new console -o MyApp
```

So'ngra yangi yaratilgan MyApp direktoriyasiga qayting, uning uchun:

```bash
> cd MyApp
```

**Bular qanday ma'noni bildiradi?**

* `dotnet new console` buyrug'i yangi konsul loyihasini yaratish uchun ishlatiladi
* `-o` parametri esa MyApp nomi papkaga loyiha fayllarini joylashligini bildiradi. output so'zidan olingan. Loyihani qaysi papka ichiga yaratish kerakligini bildiradi.
* `cd MyApp` buyrug'ining vazifasi, joriy turgan direktoriyadan berilgan manzilga o'tish kerakligini bildiradi.

MyApp papkasidagi asosiy fayl - Program.cs fayli bo'ladi.

{% code title="Program.cs" %}

```csharp
using System;
namespace myApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}
```

{% endcode %}

### Error berib qolishi mumkinmi?

`"Console Application" could not be created. Access to the path 'C:\Windows\System32\myApp' is denied.` Bizga ushbu errorni berishi mumkin. Buning ma'nosi Loyiha yaratilayotgan joyga o'zgartirish kiritish mumkin emas. Chunki bu sistema fayllari turadigan joy bo'lishi mumkin. Agar sizda ushbu xatolik bersa, siz joriy manzilni o'zgartirishingiz mumkin. Masalan: `cd d:/dasturlar`

### Dasturni ishga tushirish

CMD da quyidagi buyruqni ishga tushiring:

{% code title="Command Prompt" %}

```bash
D:\dasturlar\MyApp> dotnet run
Hello World!
D:\dasturlar\MyApp>
```

{% endcode %}

Do'stlar menimcha o'zingizning birinchi .NET ilovangizni yaratdingiz! Tabriklayman


# .NET bilan bog'liq mavhumliklardan qochish

Zohidbek Mengliboyev

**.NET Framework**, **.NET Core**, **.NET Standard**, va **.NET** kabi terminlar tez-tez uchrab turadi. Ular nima va bir-biridan qanday farq qiladi?

Bugungi postimizda shular xususida so‘z yuritamiz. 😃

.NET 6, .NET Core, .NET Framework va Xamarin ilovalar va xizmatlarni yaratishda foydalaniladigan dasturchilar uchun oʻzaro bogʻliq va bir-biriga oʻxshash platformalardir. Ushbu boʻlimda men sizlarni ushbu .NET tushunchalarining har biri bilan tanishtirmoqchiman.

## .NET Frameworkni Tushunish

.NET Framework — bu kodning bajarilishini boshqaruvchi *Common Language Runtime (CLR)* va ilovalarni yaratish uchun sinflarning boy kutubxonasini ta’minlovchi *Base Class Library (BCL)* larni o’z ichiga olgan ishlab chiqish platformasi.

Microsoft dastlab .NET Frameworkni kross-platform imkoniyatiga ega bo’lishini rejalashtirgandi, biroq Microsoft uni Windows bilan juda zo’r ishlashini amalga oshirish uchun kuchini sarfladi.

.NET Framework 4.5.2 dan boshlab u Windows operatsion tizimining rasmiy komponenti hisoblanadi.

Komponentlar o’zlarining asosiy mahsulotlari bilan bir xil qo’llab-quvvatlovga ega, shuning uchun 4.5.2 va undan keyingilari o’rnatilgan Windows operatsion tizimning yashash davri siyosatiga amal qiladi. .NET Framework bir milliarddan ziyod kompyuterlarda o’rnatildi, shuning uchun unda iloji boricha kamroq o’zgarishlar bo’lishi kerak. Hatto **bug(qurtcha)** larni tuzatish ham muammolarga olib kelishi mumkin, shunga u kamdan-kam yangilanadi.

.NET Framework 4.0 yoki undan keyingilarida .NET Framework uchun yozilgan kompyuterdagi barcha ilovalar **CLR** ning bir xil versiyasini va **Global Assembly Cache (GAC)** da saqlangan kutubxonalarni baham ko’radi, bu esa ulardan ba’zilariga o’zaro muvofiqlik uchun ma’lum bir versiya kerak bo’lsa, muammolarga olib kelishi mumkin.

{% hint style="info" %}
Yaxshi Eslatma: Amalda aytganda, .NET Framework faqat Windows uchun mo’ljallangan va eski platforma hisoblanadi. Undan foydalanib yangi ilovalar yozmang.
{% endhint %}

## Mono, Xamarin va Unity loyihalarni Tushunish

Uchinchi tomon tashkilotlar **Mono** loyihasi deb nomlangan .NET Framework tadbiqini ishlab chiqdilar. Mono — kross-platformadir, lekin u .NET Frameworkning rasmiy tatbiq etilishidan ancha orqada qoldi.

Mono Xamarin mobil platformasi, shuningdek, Unity kabi kross-platformali o’yinlarni ishlab chiqish platformalarining asosi sifatida o’z o’rnini topdi.

Microsoft Xamarinni 2016-yilda sotib oldi va endi ilgari qimmat Xamarin extension(kengaytmasi)ni Visual Studio bilan bepul taqdim etadigan bo’ldi. Microsoft faqat mobil ilovalar yaratishi mumkin bo’lgan Xamarin Studioni Mac uchun Visual Studio deb o’zgartirdi va unga konsol ilovalari va veb-xizmatlar kabi boshqa turdagi loyihalarni yaratish xizmatlarini qo’shdi. Mac uchun Visual Studio 2022 bilan Microsoft tajriba va ishlashning yaqinroq tengligini taʼminlash uchun Xamarin Studio muharriri qismlarini Windows uchun Visual Studio 2022 qismlari bilan almashtirdi. Mac uchun Visual Studio 2022 ham macOS oʻrnatilgan yordamchi texnologiyalari bilan ishonchlilik diapazoni ishini yaxshilash uchun haqiqiy macOS UI ilovasi boʻlishi uchun qayta yozildi.

## .NET Core ni Tushunish

Bugungi kunda biz chinakam platformalararo dunyoda yashayapmizki, zamonaviy mobil va bulutli rivojlanish Windows ni operatsion tizim sifatida unchalik ahamiyatsiz holga keltirdi. Shu sababli Microsoft .NET ni Windows bilan yaqin aloqalaridan ajratish ustida ishlamoqda. .NET Frameworkni chinakam kross-platformali bo’lishi uchun qayta yozish paytida ular endi core(o‘zak) hisoblanmaydigan asosiy qismlarni qayta qurish va olib tashlash imkoniyatidan foydalanganlar.

Ushbu yangi mahsulot .NET Core brendi ostida bo’lib, .NET Frameworkdagi CLR nomi **CoreCLR** ga, BCL esa soddalashtirilib **CoreFX** ga o’zgartirildi va kross-platforma xususiyati qo’shildi.

.NET Core tez harakat qiladi va u ilova bilan yonma-yon joylashtirilishi mumkinligi sababli, u tez-tez o’zgarishi mumkin, chunki bu o’zgarishlar bir xil mashinadagi boshqa .NET Core ilovalariga ta’sir qilmaydi. Microsoft .NET Core va zamonaviy .NET ga qilgan ko’pgina yaxshilanishlarni .NET Frameworkga osongina qo’shib bo’lmaydi.

## .NET ning o‘ziga Tushunish

2020-yil may oyida boʻlib oʻtgan Microsoft Build dasturchilar konferensiyasida .NET jamoasi .NET ni birlashtirish boʻyicha rejalari kechiktirilganini eʼlon qildi. Ular .NET 5 2020-yil 10-noyabrda chiqarilishini va u mobildan tashqari barcha turli .NET platformalarini birlashtirishini aytishdi. 2021-yil noyabr oyida .NET 6 ga qadar mobil qurilmalar ham birlashgan .NET platformasi tomonidan qo‘llab-quvvatlanadi.

.NET Core nomi .NET deb o‘zgartirildi va asosiy versiya raqami .NET Framework 4.x bilan chalkashmaslik uchun to‘rtinchi raqamni o‘tkazib yubordi. Microsoft har yili noyabrda yillik yirik versiyalarini chiqarishni rejalashtirmoqda, xuddi Apple har sentyabrda iOS ning asosiy versiya raqamlarini chiqarganidek.

Quyidagi jadvalda zamonaviy .NET ning asosiy versiyalari qachon chiqarilgani, kelajakdagi relizlar qachon rejalashtirilganligi ko‘rsatilgan:

![.NET versiyalari va relizlari](https://user-images.githubusercontent.com/91861166/193436967-59b98550-9f87-4bf1-b0de-583804def399.jpeg)

## Zamonaviy .NET nimasi bilan farq qiladi?

Zamonaviy .NET eski .NET Framework bilan solishtirganda *kross-platform* qilingan. Bu “**open-source**” bo’lib, Microsoft yaxshilanishlar va o’zgarishlar haqida qarorlar qabul qiladi. Microsoft zamonaviy .NET ish faoliyatini yaxshilash uchun alohida kuch sarfladi.

Eski va kross-platform boʻlmagan texnologiyalarni olib tashlash tufayli u .NET Frameworkning soʻnggi versiyasidan kichikroq. Misol uchun, **Windows Forms** va **Windows Presentation Foundation (WPF)** kabi ichki platformalar *foydalanuvchi grafik interfeysi (GUI)* ilovalarini yaratish uchun ishlatilishi mumkin, lekin ular Windows’ga qattiq bog’langan, shuning uchun ular macOS va Linuxda ishlatiladigan .NET da qo’shilmaydi.

### Windows Ilovalar

Zamonaviy .NET ning xususiyatlaridan biri bu .NET Core 3.1 yoki undan keyingilarining Windows versiyasiga kiritilgan *Windows Developer Pack* yordamida eski Windows Forms va WPF ilovalarini ishga tushirishni qo‘llab-quvvatlashdir, shuning uchun macOs va Linux SDK laridan kattaroqdir. Agar kerak bo’lsa, eski Windows ilovangizga kichik o’zgarishlar kiritishingiz mumkin, so’ngra yangi xususiyatlar va ish faoliyatini yaxshilashdan foydalanishda uni .NET 6 uchun qayta qurishingiz mumkin.

### Web Ilovalar

**ASP.NET Web Forms** va **Windows Communication Foundation (WCF)** eski veb-ilova va xizmat ko’rsatish texnologiyalari bo’lib, bugungi kunda kamdan-kam dasturchilar yangi loyihalarni ishlab chiqish uchun tanlamoqda, shu sababdan ular zamonaviy .NET dan ham olib tashlangan. Buning o’rniga ishlab chiquvchilar ASP.NET MVC, ASP.NET Web API, SignalR va gRPC dan foydalanishni afzal ko’rishadi. Ushbu texnologiyalar qayta ishlab chiqilgan va *ASP.NET Core* deb nomlangan zamonaviy .NET da ishlaydigan platformaga birlashtirilgan.

### Ma’lumotlar Bazalari

Entity Framework (EF) 6 — bu Oracle va Microsoft SQL Server kabi relyatsion ma’lumotlar bazalarida saqlanadigan ma’lumotlar bilan ishlash uchun mo’ljallangan object-relational mapping (ORM) texnologiyasi. U yillar davomida o’ziga yuk ortib bordi, shuning uchun kross-platformali API qisqartirildi, Microsoft Azure Cosmos DB kabi non-relational(aloqador boʻlmagan) maʼlumotlar bazalari uchun qoʻllab-quvvatlandi va Entity Framework Core deb oʻzgartirildi. Agar sizda eski EF dan foydalanadigan ilovalaringiz bo’lsa, 6.3 versiyasi .NET Core 3.0 yoki undan keyingi versiyalarida qo’llab-quvvatlanadi.

## .NET Standard ni Tushunish

2019-yilda .NET bilan bog‘liq vaziyat quyidagi ro‘yxatda ko‘rsatilganidek, Microsoft tomonidan boshqariladigan uchta shoxli .NET platformasi mavjud edi:

• .NET Core: Kross-platforma va yangi ilovalar uchun • .NET Framework: Eski ilovalar uchun • Xamarin: Mobil ilovalar uchun

Har birining kuchli va zaif tomonlari bor edi, chunki ularning barchasi turli ssenariylar uchun tuzilgandi. Bu dasturiy ta’minot muhandislari uchta platformani o’rganishi kerak bo’lgan muammoga olib keldi, ularning har biri zerikarli g’alatilik va cheklovlarga ega.

Shu sababli, Microsoft .NET Standard ni belgiladi va bu barcha .NET platformalari moslik darajasini ko’rsatish uchun amalga oshirishi mumkin bo’lgan API to’plamining spetsifikatsiyasi. Misol uchun, asosiy qo’llab-quvvatlash platforma .NET Standard 1.4 bilan mos kelishi bilan ko’rsatilgan.

.NET Standard 2.0 va undan keyingi versiyalari bilan Microsoft har uch platformani zamonaviy minimal standartda birlashtirdi, bu esa ishlab chiquvchilarga .NET ning har qanday istaklari o’rtasida kod almashishni ancha osonlashtirdi.

.NET Core 2.0 va undan keyingilarida bu dasturchilar .NET Framework uchun yozilgan eski kodni oʻzaro platforma .NET Corega portlashi kerak boʻlgan yetishmaydigan API larning koʻpini qoʻshishdi. Biroq, ba’zi API lar amalga oshirilgan, ammo ishlab chiquvchiga ulardan foydalanmaslik kerakligini ko’rsatish uchun istisno qiladi. Bu odatda siz .NET ishlatadigan operatsion tizimdagi farqlarga bog’liq.

Qolaversa, .NET Standard shunchaki standart ekanligini tushunish muhimdir. Frontenddan xabaringiz bo’lsa, HTML5 ni qurilmangizga o’rnatolmaganingizdek, bu yerda ham .NET Standardni o’rnatishning iloji yo’q. Chunki, u dasturiy ta’minotning bir qismi emas, shunchaki texnologiyalar to’plami xolos. HTML5 dan foydalanish uchun HTML5 standartini amalga oshiradigan veb-brauzerni o’rnatishingiz kerak.

.NET Standard dan foydalanish uchun .NET Standard spetsifikatsiyasini amalga oshiradigan .NET platformasini o’rnatishingiz kerak. Oxirgi .NET Standard, 2.1 versiyasi .NET Core 3.0, Mono va Xamarin tomonidan amalga oshiriladi. C# 8.0 ning ayrim xususiyatlari .NET Standard 2.1 ni talab qiladi. .NET Standard 2.1 .NET Framework 4.8 tomonidan amalga oshirilmagan, shuning uchun biz .NET Frameworkni eskirgan sifatida talqin qilishimiz kerak.

2021-yil noyabr oyida .NET 6 ning chiqarilishi bilan .NET Standardga ehtiyoj sezilarli darajada kamaydi, chunki endi barcha platformalar, jumladan, mobil qurilmalar uchun yagona .NET mavjud. .NET 6 da bitta BCL va ikkita CLR mavjud: CoreCLR veb-saytlar va Windows Desktop ilovalari kabi server yoki desktop stsenariylari uchun optimallashtirilgan va Mono ish vaqti cheklangan resurslarga ega mobil va veb-brauzer ilovalari uchun optimallashtirilgan.

Hozir ham .NET Framework uchun yaratilgan ilovalar va veb-saytlar qo‘llab-quvvatlanishi kerak, shuning uchun siz eski .NET platformalari bilan o’tmishda mos keladigan .NET Standard 2.0 sinf kutubxonalarini yaratishingiz mumkinligini tushunish zarurdir.

## .NET Texnologiyalarini Taqqoslash

![.NET texnologiyalari solishtiruvi](https://user-images.githubusercontent.com/91861166/193437076-54acd1c9-42f1-4738-ae40-a3c4739a4775.jpeg)

Bu yerda soddalashtirish maqsadida, **Zamonaviy .NET** atamasi deb .NET 6 va .NET Core’dan kelgan uning .NET 5 kabi oldingilariga murojaat qilish uchun foydalanildi. **Eski .NET** atamasidan .NET Framework, Mono, Xamarin va .NET Standard ga murojaat qilish uchun ishlatildi. Xulosa qilib aytganda, Zamonaviy .NET — bu eski platformalar va standartlarni birlashtirilgani.


# .NET asoslari


# MSIL

Og'abek Ochilov

Biz sizlar bilan barcha dotnet dasturchilari bilishi lozim bo’lgan mavzu - o’zimiz yozgan kodimizning qanday kompilyatsiya bo’lishini ko’rib chiqamiz.

.Net da MSIL nima?

Dasturni ishlab chiqish jarayonida .Net platformasi turli dasurlash tillari(C#, F#,Visual basic) uchun har birida alohida kompilyatorlardan foydalanadi. Biz yozgan kodimiz kompilyatsiya jarayonidan keyin, har bir .Net kompilyatori kodimizni **intermediate code** (o’rta kod) ga o’girib beradi, va har bir muhit bunda MSIL dan foydalanadi.

Bu bo’limda biz MSIL nima ekanligini batafsil o’rganamiz.

## MSIL nima?

Microsoft Intermediate Language (MSIL) ba’zan Common Intermediate Language (CIL) nomi bilan ham ataladi. U turli kompilyatorlar (C#, VB, .NET va boshqalar) tomonidan ishlab chiqariladi va tillarning xos kompilyatorlaridan mutlaqo turli tushuncha hisoblanadi.

NET Framework SDK (FrameworkSDKBinildasm.exe) tarkibiga kiritilgan ILDasm (Intermediate Language Disassembler) dasturi foydalanuvchilarga MSIL kodini inson o‘qiy oladigan formatda ko‘rish imkonini beradi. Ushbu dastur yordamida biz MSIL kodini istalgan.NET bajariladigan faylida (EXE yoki DLL) ko'rishimiz mumkin.

## Execution (bajarish) jarayoni CLR(Common language runtime) da

Quyidagi jarayonda biz MSIL ishlashi va JIT kompilyatorining MSIL ni mashina kodiga o’girishi ko’rsatib beramiz.

• CLR kompilyatsiya qilish vaqtida tilga xos kompilyator manba kodini MSIL ga o'zgartiradi. MSILga qo'shimcha ravishda, kompilyatsiya paytida metama'lumotlar hosil bo'ladi. Metama’lumot koddagi turlarning ta'rifi, assembly versiyasi, qo’shimcha ulangan tashqi assembly ro’yxati, shuningdek, runtime(ish vaqti) haqidagi ma'lumot kabi elementlarni o'z ichiga oladi.

• MSIL CLI(Common Language Infrastructure ) assembleyida jamlanadi. Bu assembly xavfsizlik, versiyalashtirish, deployment va boshqa maqsadlarda foydalanish uchun qurilgan kodlar kutubxonasi hisoblanadi. U ikki turga bo'linadi: process assembly (EXE) and library assembly (LIB) (DLL).

• Keyin JIT kompilyatori Microsoft Intermediate Language (MSIL) ni o'zi bajarayotgan kompyuter muhiti bilan bog'liq bo'lgan mashina kodiga tarjima qiladi. MSIL kodimizni turli talablar asosida mashina kodiga aylantiriladi, ya'ni JIT kompilyatori butun MSIL emas, balki faqat zarur bo'lgan MSIL ni kompilyatsiya qiladi.

• So’ngra JIT kompilyatori kompyuter protsessorida bajariladigan mashina kodini hosil qiladi.

Umumiy ko’rinishda quyidagi jarayon sodir bo’ladi:

![Execution process in Common Language Runtime (CLR)](https://user-images.githubusercontent.com/91861166/158581645-c6c04764-c958-4048-9af0-bccf3f36d321.png)

**.Net da MSIL ning rollari**

1. **Platform Independence:** - Platforma mustaqilligi bir xil bayt kodli buyruq fayli istalgan platformaga joylashtirilishi mumkinligini anglatadi. Boshqacha qilib aytganda, MSIL ma'lum bir protsessorga bog'liq bo'lmagan portativ ko'rsatmalar to'plamini belgilaydi.
2. **Performance Improvement:** - Bir vaqtning o'zida butun dasturni yaratish o'rniga, JIT kompilyatori kerak bo'lganda kodning har bir qismini kompilyatsiya qiladi. Biz kodni bir marta kompilyatsiya qilganimizda, kompilyatsiya toki application (ilova) yaratgunimizga qadar saqlanib qoladi, shuning uchun biz kodimizni qayta run(yurg’izish) qilishimizga hojat qolmaydi. Bu usul to'liq dastur kodini boshidan kompilyatsiya qilishdan ko'ra tezroq. Bundan tashqari, MSIL kodini ishga tushirish native mashina kodini ishlatish kabi tez ekanligini ko'rsatadi.
3. **Language Interoperability:** - Tilning o’zaro muvofiqligi uning foydalanuvchanligini oshiradi. Bitta tildan MSIL ga kompilyatsiya qilish mumkin va natijada olingan kod boshqa tildagi kodga (MSIL ga kompilyatsiya qilingan) mos keladi. Til tanlash ishlab chiquvchilar tomonidan nazorat qilinmaydi. Osonroq tushuntiradigan bo’lsak bitta dasturda bir nechta tillardan ham foydalanish mumkin. Quyidagi rasmda yanayam tushunarliroq bo’ladi degan umiddaman.

![](https://user-images.githubusercontent.com/91861166/158581997-0982ead2-f485-4f3a-98dc-5deabc007dca.png)

1. **Reducing maintenance headaches:** - CLR MSIL kodini xavfsizlik standartlarga mos kelishini tekshiradi. Build time vaqtida xavfsiz bo’lmagan qismlarni aniqlashi mumkin, bu esa texnik xizmat ko’rsatish bosh og’riqlarini sezilarli darajada kamaytiradi.

Xulosa o’rnida shuni aytishimiz mumkinki, MSIL kodi har bir.NET assemblyning asosidir. MSIL instruksiyalar toʻplamini qanchalik koʻp bilsangiz, mukammal .NET ilovalarini ishlab chiqishni shunchalik yaxshi tushunasiz.


# Memory Management


# Stack & Heap

Dilafruza Jo'raboyeva

Assalomu alaykum, biz hozir dasturingiz run bo‘lganda, xotira bilan bog'liq umumiy qanday jarayonlar ketishi haqida sal chuqurroq yoritib berishga harakat qilamiz.

**RAM** => Random access memory, biz bilgan o‘sha tezkor xotira. Dastur ishga tushganda, dasturda foydalanilgan vaqtinchalik ma’lumotlar shu qismda saqlanadi. **CLR** xotirani oson boshqarishi uchun, xotirani ba’zi qismlarga ajratadi:

1. **Stack** - bu ma’lumotlarni **LIFO** ko‘rinishida saqlovchi ma’lumotlar tuzilmasi;
2. **Heap** - bu xotiraning dynamic memory allocation’ga javob beradigan qismi;
3. **Native** Code Instructions - bu mashina tiliga mos bo‘lgan code saqlanadigan xotiraning bir qismi;

![Random access memory(RAM)](/files/ntKjPl3KJF50Or70fhfv)

### Keling, birinchi **Stack** nima ekanligi haqida gaplashamiz :)

**Stack** => Xotiraning bu qismi asosan local o‘zgaruvchilarni saqlashga va method chaqiruvlarini boshqarishga xizmat qiladi. Unda ma’lumot qo‘shish va o‘chirish judayam tez bo‘ladi. Stack har bir method call qilinganda o‘sha method uchun mahsus **Stack Frame** yaratadi va bu jarayon **CallStack** deb ataladi.

Stack Frame o‘zi nima?

**Stack Frame** => Dasturning runtime’da har bitta call qilingan method’lar uchun alohida alohida bir biridan **izolyatsiyalangan** Stack Frame’lar yaratiladi, va method’dagi **local** o‘zgaruvchilar, code’ning qaysi qismi, qaysi qatori haqidagi address shu Stack Frame’da saqlanadi. Refence type’li, yoki **global** o‘zgaruvchi bo‘lsa, o‘zi Heap’da joylashadi va address'i shu Stack Frame'ga reference qilib qo‘yiladi. Method o‘z ishini yakunlasa, Stack Frame Stack’dan **Pop** qilinadi, ya’ni tozaladi.

### **Global** va **local** o‘zgaruvchi deb nima nazarda tutildi?

Aynan bu **Global** o‘zgaruvchi deyilganda, bir necha method’larda qayta qayta ishlatilishi mumkin bo‘lgan reference va value type’ga mansub o‘zgaruvchilar nazarda tutildi. Xususan, class’ning property, field’lari, .. va hokazo.

**Local** o‘zgaruvchi deb esa, faqat aynan shu method’da ishlatilgan, va method o'z ishini tugatsa, uning ham yashash vaqti tugaydigan o‘zgaruvchilarga aytilgan. Value type bo‘lgan method parametr’lari, .. va hokazo.

Ya’ni, value type’ga mansub o'zgaruvchilar qayerda yaratilishiga qarab xotira tanlaydi. Unuting, "value type’li o'zgaruvchilar faqat Stack’da joylashadi" degan gapni :)

Nega value type’li o'zgaruvchilar Heap’da ham joylashishi kerak? Nega Stack’da joylashavermaydi ular?

Bir value type’ga doir bo‘lgan o‘zgaruvchi Heap’da joylashishi uchun u bir nechta method’larda bir necha marta ishlatilishi kerak bo‘ladi. Yuqorida aytganimday, Stack Frame’lar bir biridan izolyatsiyalangan bo‘ladi. Bu shuni anglatadiki, siz birinchi method’da ishlatilgan o‘zgaruvchingizni ikkinchi method’da ishlata olmaysiz. Shu sababdan global value type bo‘lgan o‘zgaruvchilar ham Heap’da saqlanadi, har qaysi Stack Frame uchun uni address’i reference qilib qo‘yiladi va bu sizga sizning Global o‘zgaruvchingizni istalgan method’ingizda, istalgan marotaba ishlatish imkonini beradi.

### Stack’dan Stack Frame’ni **Pop** qilish jarayoni qanday bo‘ladi?

Yuqorida aytganimdek, Method o‘z ishini yakunlasa, Stack Frame’ham Stack’dan Pop qilinadi va shu bilan birgalikda, method’da ishlatilgan local va global o‘zgaruvchilar ham xotiradan tozaladi. Local o‘zgaruvchilar birdaniga Stack Frame’dan tozalanadi. Global o‘zgaruvchilar esa Heap’da saqlanib turibdi desak, bu holatda Global o‘zgaruvchini Stack Frame’dan reference’i uziladi, ya’ni qiymati null’ga tenglanadi. Heap’ni atrofini davomli ravishda aylanib yuruvchi o‘sha mashhur **Garbage Collector** refernce’i uzilgan ma’lumotlarni qidirib yuradi, va ularni tez-tez tozalab turadi. Agar bunday bo'lmaganda(tozalamagan taqdirida), **Memory Leak**(keraksiz ma’lumotlar to‘lib ketishi)ga olib kelar edi.

![Stack'dan Stack Frame'ni pop qilish jarayoni](/files/vn0jlXums8Pu1OqpEWH0)

Local value type'ni stack'da saqlanishiga doir istisnolar:

1. **Anonim Funksiyalar**
2. **Asinxron Funksiyalar**, shu holatda local o‘zgaruvchimiz ham Heap’da vaqtinchalikka joylashib turadi, Stack Frame Pop bo‘lsa, GC borib, o‘zgaruvchini ham Heap'dan tozalab yuboradi.

### Endi navbat **Heap**’ga keldi)

**Heap** => Xotiraning bu qismida obyektlar va reference type'ga tegishli ma'lumotlar saqlanadi, qiymati Heap'da, address’lari esa Stack’da saqlab boriladi. U address’ga reference qilib qo‘yiladi.

Lekin bu hali hammasi emas, keling sal chuqurroq yondashamiz)

Heap o‘zi nima uchun yaratilgan? Bizga Stack’ni o‘zi yetmasmidi?

Bu yerda shuni aytish joizki, Heap’ning asosiy ustunlik taraflari ma’lumotlarni betartib holatda joylashtirishi(unlimited joy), collection’larni boshidagi object’ni **root reference** qila olishidir.

Aytaylik, bizdagi Stack Frame’da global reference tip bo‘lgan o‘zgaruvchimiz bor, va u collection, agar uni boshqa Stack Frame’ga copy qilmoqchi bo‘lsak elementlarini bitta bitta o‘tkazib chiqishga to‘g‘ri kelar edi. Heap bor bo‘lganligi uchun shunchaki o‘sha collection’ning root reference’i ulab qo‘yiladi xolos)

Heap’ning mavzuga doir tashkil topgan qismlarini aytib o'taman:

1. **LOH** => Large Object Heap(85 000 baytdan katta bo‘lgan ma’lumotli o‘zgaruvchilar saqlanadi)
2. **SOH** => Small Object Heap(85 000 baytdan kichik bo‘lgan ma’lumotli o‘zgaruvchilar saqlanadi)
3. **Code Heap**(0,1’lar saqlanadi :))

LOH va SOH’lar **Managed Heap** deya yuritiladi.

LOH’ning ichidan **String pool** ham o‘rin olgan hisoblanadi.

![RAM xotirasining umumiy tuzulishi](/files/zH92SAcEf4H5SoDl1umG)

Bu safargi, Heap va Stack xotira yuzasidan olib borgan kichik chuqurlashuvimiz shulardan iborat edi, e'tiboringiz uchun rahmat)


# CLR

Kanalbekov Umarbek

Common Language Runtime(CLR) .NET dasturlarining ishlash jarayonini boshqaradi. O'z vaqtida kompilyator kompilyatsiya qilingan codeni yani (MSIL) codeni mashina codega ( 0 va 1 larga) kompilyatsiya qiladi.

CLR tomonidan taqdim etiladigan xizmatlar xotirani boshqarish, xatoliklar bilan ishlash, xavfsizlik va boshqalarni o'z ichiga oladi.

### Common Language Runtime(CLR)ni to’liqroq tushuntiradigan bo’lsam:

CLR .NET ning asosiy komponentidir. Bu codelarni boshqaradigan va turli xizmatlarni taqdim etish orqali ishlab chiqish jarayonini osonlashtirishga yordam beradigan .NET runtime muhitidir. Asosan, u har qanday .NET dasturlash tilidan qat'iy nazar .NET dasturlari bajarilishini boshqarish uchun javobgardir. Common Language Runtime ostida ishlaydigan code boshqariladigan code deb ataladi. Boshqacha qilib aytganda, CLR .NET uchun boshqariladigan runtime muhitini ta'minlaydi, deb ayta olamiz.

![](https://user-images.githubusercontent.com/91861166/223932932-6b84b63b-51d9-43a9-be46-db35b6e46da1.png)

### C# dasturini Run qilishda CLR ning roli.

Faraz qilaylik, siz C# dasturini yozdingiz va uni program deb nomlanuvchi faylga saqladingiz. Tilga xos kompilyator manba codeini metama'lumotlari bilan birga CIL (Common Intermediate Language) yoki IL (Intermediate Language) deb ham ataladigan MSIL (Microsoft Intermediate Language) ga kompilyatsiya qiladi.

Endi CLR ning navbati. CLR MSIL codega xizmatlar va runtime ish muhitini taqdim etadi. Ichki CLR MSIL codeni keyinchalik protsessor tomonidan bajariladigan mashina codega aylantiruvchi JIT (Just-In-Time) kompilyatorini o'z ichiga oladi. CLR MSIL codeini boshqaradigan dasturlash tili, muhiti, versiyasi va classlari haqida ma'lumot beradi. CLR keng tarqalgan bo'lgani uchun u boshqa tilda yozilgan classga boshqa tilda yozilgan classni ulash imkonini beradi.

### Garbage Collection (GC)

Do’stlar, bir asosiy narsani, CLR ning asosiy terminlaridan biri Garbage Collection (GC) keling uni ham bir ko’rib chiqsak.

Garbage Collection (GC) - bu .NET va boshqa ko'plab dasturlash tillarida qo'llaniladigan xotirani boshqarish usuli. C# da Garbage Collection(GC) xotirani boshqarish va ilova tomonidan foydalanilmayotgan xotirani avtomatik ravishda bo'shatish uchun javobgardir. Garbage Collection (GC) dastur xotirasini vaqti-vaqti bilan skanerlash orqali ishlaydi va qaysi ob'ektlar hali ham foydalanilayotganligini va qaysi biri kerak emasligini aniqlaydi. Endi foydalanilmayotgan ob'ektlar belgilanadi va ular band qilib turgan xotira joyi Garbage Collection(GC) tomonidan avtomatik ravishda bo'shatiladi.

Garbage Collection(GC) asosiy xususiyatlaridan ba'zilari: Avtomatik xotirani boshqarish: Garbage Collection(GC) bilan ishlab chiquvchilar xotirani qo'lda ajratish yoki bo'shatish haqida tashvishlanishlari shart emas. Garbage Collection(GC) avtomatik ravishda xotirani boshqarishga yordam qiladi, bu esa oshiqcha ma’lumotlar bilan xotira to’lish xavfini va boshqa muammolarni bartaraf etishga yordam beradi. Ilova ishlashiga kam ta'sir etadi: Garbage Collection(GC) orqada ishlaydi va odatda dastur ishlashiga kam ta'sir qiladi. Biroq, ba'zi hollarda, keraksiz ma’lumotlarni yig’ish ko’proq vaqit olishi mumkin, ayniqsa, bir vaqtning o'zida katta hajmdagi xotirani bo'shatish kerak bo'lganda, dasturda qisqa pauza yoki tezlikga biroz ta’sir etishi mumkin. Avlodga asoslangan yig'ish: Garbage Collection(GC) xotirani boshqarishda avlodga asoslangan yondashuvdan foydalanadi. Ob'ektlar dastlab "yosh" avlodda taqsimlanadi va agar ular bir nechta tekshiruv davrlarida omon qolsa, "eski" avlodga o'tkaziladi. Ushbu yondashuv ishlatilmayotgan ma’lumotlarni yig’ib olish uchun zarur bo'lgan vaqtni qisqartirishga yordam beradi, chunki ko'pchilik ob'ektlar yosh avlodda yig'iladi. Yakunlash: Garbage Collection(GC) ob'ektlarni yo'q qilishdan oldin tozalash vazifalarini bajarishga imkon beruvchi jarayon bo'lgan yakunlashni qo'llab-quvvatlaydi. Yakunlovchilari bo'lgan ob'ektlar boshqa barcha ob'ektlar yig'ilgandan so'ng, Garbage Collection(GC) tomonidan qayta ishlanadigan alohida yakunlash navbatiga o'tkaziladi.

### Boshqariladigan code va boshqarilmaydigan code

Keling boshqariladigan code va boshqarilmaydigan code haqida gaplashsak. Boshqariladigan code CLR (Common Language Runtime) tomonidan boshqariladigan code . Boshqarilmaydigan code esa to'g'ridan-to'g'ri operatsion tizim tomonidan bajariladigan code. Quyida boshqariladigan code va boshqarilmaydigan code o'rtasidagi muhim farqlar keltirilgan:

| Boshqariladigan code                                                                     | Boshqarilmaydigan code                                                                     |
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| CLR tomonidan boshqariladi.                                                              | U to'g'ridan-to'g'ri operatsion tizim tomonidan o’qiladi.                                  |
| Yozilgan dastur xavfsizligini ta'minlaydi.                                               | Bu ilova uchun hech qanday xavfsizlikni ta'minlamaydi.                                     |
| Xotira buferining to'lib ketishi sodir bo'lmaydi.                                        | Xotira buferi to'lib ketishi mumkin.                                                       |
| U axlat yig'ish, xatoliklarni qayta ishlash va boshqa runtime xizmatlarini taqdim etadi. | U axlat yig'ish, xatoliklarni qayta ishlash va boshqa runtime xizmatlarini taqdim etmaydi. |
| Manba codei IL yoki MSIL yoki CIL oraliq tilda tuzilgan .                                | Manba codei to'g'ridan-to'g'ri 0 va 1 larga kompilyatsiya qilinadi.                        |


# Basics

"C# dasturlash tiliga kirish" deb boshlashadi hamma, biz esa "bosingiz" deb start beramz!

Ushbu Basic qismni sizlar bilan birgalikda teng 3 qismga bo'lamiz. Kim so'kadi? Hech kim... . Keling men o'sha bo'lingan qismlarni ko'rsataman.

```csharp
using System;

namespace dotnetuz
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //Your code goes here
            Console.WriteLine("Hello, world!");
        }
    }
}

//from C# 9.0 System.Console.WriteLine("Hello World!"); enough for us! :)
```

Hamma ma'lumot beradi, keyin esa kodni ko'rsatadi. Men esa sizga kodni berib, shu kodni o'rgatmoqchiman! Nima deysiz?


# Starter (boshlang'ich)


# Java vs C\#

Suxrob Xayitmurodov

**Siz bilishingiz kerak bo’lgan eng muhim faktlar!** <br>

![techempower.com orqali solishtirilgan](/files/-M_g09rM-6osK6L2CMAi)

{% hint style="info" %}
Techempower linki:

<https://www.techempower.com/benchmarks/#section=data-r20&hw=ph&test=plaintext>
{% endhint %}

\
Assalamu alaykum, bo’lajak C# dasturchilari, galdagi mavzuyimizga xush kelibsiz. Bu mavzu ikki raqobatdosh tillari Java va C# haqida, ularning ustunlik va kamchilik tomonlari haqida bo'ladi.

![](/files/-MLWfQBsJ5K2HrTo_35s)

Java Object-Oriented (ob'ektga yo'naltirilgan) va (class-based) klasslarga asoslangan dastrulash tilidir. Dasturchilar Javada bir marta kod yozishadi, har qanday joyda (run) ishlata olishadi. Java (source) manba kodlarini, Java kompilyatori uni (bytecode) bayt kodlarga o'zgartiradi va keyinchalik ushbu kompilyatsiya qilingan bayt kod JRE (Java Runtime Environment) yordamida istalgan operatsion tizimda ishlash imkoniyatini beradi.

C# ham (Object-Oriented) ob'ektga yo'naltirilgan, funksional, (generic and component-oriented)  generic va komponentlarga yo'naltirilgan asosiy tillardan hisoblanadi. OOP, funksiya va generic tiplar haqida [Essential (muhim)](https://dot-net.uz/basic/essential) bo'limimizda o'qishingiz mumkin. Bu til turli xil dasturlarni tuzish uchun ishlatilinadi. Windows operatsion tizimida (windows application) windows dasturlarini tuzishda va o'yinlarini yasashda ushbu til absolyutno kuchli til hisoblanadi. Veb-ishlab chiqishni C# yordamida ham samarali bajarish mumkin va u mobil ishlanmalar uchun tobora ommalashib bormoqda.

### Birma-bir taqqoslaymiz!

Quyida Java va C# o'rtasidagi eng yaxshi 7 taqqoslashlar keltirilgan:

> ASOSIY FARQLARI
>
> * Java Java Runtime Environment (JRE) da ishlaydi, C# esa Common Language Runtime (CLR) da ishlashga mo'ljallangan.
> * Java class-based ya'ni klasslarga asoslangan Ob'ektga yo'naltirilgan til, C# esa Ob'ektga yo'naltirilgan, funksional va komponentlarga yo'naltirilgan til!
> * Java operatorning yuklanishini qo'llab-quvvatlamaydi, C# esa bir nechta operatorlar uchun operatorning yuklanishini ta'minlaydi.
> * Java pointers (ko'rsatgichlar)ni qo'llab-quvvatlamaydi, C# esa faqat xavfli rejimda qo'llab-quvvatlaydi.
> * Javada massivlar Object kutubxonasiga tegishli bo'lsa, C# da massivlar System kutubxonasiga tegishli

![stackoverflowda Java va C# savollarining berilishi statistikasi](/files/-M_p-8EOfcbr-C_7v3Mw)

| Xususiyatlari                                    | Java                                                                                                    | C#                                                                                              |
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| Ishlab chiqarilishi                              | Sun Microsystems tomonidan ishlab chiqilgan                                                             | Microsoft .NET ning bir qismi sifatida ishlab chiqilgan                                         |
| Ecosystem                                        | Ulkan ochiq manbali kod tizimiga ega                                                                    | Microsoft platformalari uchun dasturiy ta'minotni ishlab chiqish uchun foydalaniladi            |
| Delegatlar                                       | Delegatlarga o'xshagan funksiyalarga erishish uchun interfeysdan foydalanishni talab qiladi             | C# o'zining metod sifatida xizmat qiladigan delegatlari mavjud                                  |
| Istisno holatlari (code reviewing)               | Istisno faqat bitta turga ega                                                                           | Tekshirilgan va tekshirilmagan istisnolarni ajratib turadi                                      |
| Goto                                             | Java ushbu operatorni qo'llab quvvatlamaydi                                                             | C# ushbu operatorni qo'llab quvvatlaydi                                                         |
| Polymorphism                                     | Asosiy sinfda "virtual" kalit so'zni chaqiradi va olingan sinfda "bekor qilish" kalit so'zini ishlatadi | Odatiy holat bo'yicha polimorfizmni yoqadi. By default                                          |
| Xavfsizlik                                       | Himoyalangan                                                                                            | Himoyalanmagan                                                                                  |
| Qo'shimcha kompilyatsiyani qo'llab quvvatlaydimi | Java qo'shimcha kompilyatsiyani qo'llab quvvatlamaydi                                                   | C# protsessor ko'rsatmalari yordamida qo'shimcha kompilyatsiya xususiyatini qo'llab-quvvatlaydi |
| Cross-platform                                   | Java o'zining baytkodi bilan yetarlicha kross-platforma hisoblanadi                                     | C# ham kross-platforma, lekin Javaga taqqoslaganda, C# bu xususiyatini rivojlantirishi zarur    |
| IDE                                              | Eclipse, NetBeans, IntelliJ IEDA                                                                        | Visual Studio, MonoDevelop, #Develop, VS Code                                                   |
| Runtime                                          | Java JVM (Java Virtual Machine) yordamida kodni ishga tushiradi                                         | C# CLR (Common Language Runtime) yordamida kodni ishga tushiradi                                |
| O'rtacha ish haqi                                | 2020 - yilga ko'ra Java dasturchilari o'rtacha yiliga $102, 633 ishlab topishadi                        | 2020 - yilga ko'ra C# dasturchilari yiliga $108, 145 ishlashadi                                 |

### Javaning ustunlik tomonlari

1. To'liq har bir Java kodlari detallarigacha tushuntirib berilgan.
2. Dasturchilarning ma'lum bir qismi, ya'ni dasturchilarning ko'proq qismini Java mutaxasislari tashkil etadi.
3. Java bir vaqtning o'zida ko'plab vazifalarni bajarishga imkon beradigan ko'p tarmoqli muhitga ega.
4. Kutubxonalarni boshqarish juda oson.

### C# ning ustunlik tomonlari

1. Tegishli lambda va genericlarni qo'llab-quvvatlaydi.
2. Microsoft Corporation tomonidan qo'llab-quvvatlangan. (O'sha mashhuuur kompaniya).
3. Avtomatik tarzda keraksiz kodlarni ajratadi. Warning deb chiqadi.
4. Maydonlar get va set metodlari bilan birga keladi. Bu esa C# da kod yozishni yanada osonlashtiradi.
5. Xotirani avtomatik boshqarish imkoni bor.

### Javaning kamchiliklari

1. JIT kompilyatori dasturni nisbatan sekinlashtiradi.
2. Java yuqori xotira va ishlash talablariga ega. Bu esa qimmat hardware kerak degani.
3. Pointers kabi past darajadagi dasturiy tuzilmalarni qo'llab-quvvatlamaydi.
4. Javada keraksiz kodlar ustida hech qanday nazorat yo'q, chunki Java delete(), free() kabi funksiyalarni o'z ichiga olmaydi.

### C# ning kamchiliklari

1. C# .NET frameworkining internal qismidir, shuning uchun dasturni ishlaydigan server Windowsga asoslangan bo'lishi kerak.
2. C# moslashuvchan emas, chunki u asosan .NET frameworkiga bog'liq.

![Bolakayni qarang...:)))](/files/-MLWg4k696utwdz2pnOC)


# C# Tarixi

Suxrob Xayitmurodov

Ushbu maqolamizda sizlarga C# dasturlash tili tarixi haqida qisqacha ma’lumot berishga harakat qilamiz. Agarda siz dasturlash olamida yangi va nimadan boshlashi bilmay turgan bo’lsangiz, ushbu kamtargina maqolachamiz aynan siz uchun. Nega bu til juda mashhur? Ushbu mashhur dasturlash tilining tarixini ko’rib chiqing.

C# ning kelib chiqishi 2000-yillarga borib taqaladi. O’sha yillarda Microsoft ushbu dasturlash tilini o’zlari uchun yaratshdi. Dastlab C#, JavaScript bilan raqobatlashayotgan Java tillariga javob sifatida, ya’ni Microsoftning talabiga Java javob bera olamgani tufayli Microsoft Visual Studio 2002 bilan birglikda ishlab chiqilgan til edi. C# va Java ham dastlabki davrlardan tan olinishi uchun raqobatlashayotgan edi. Darhaqiqat, bu ikkisi bir biridan ancha ko’chirmachiliklar qildi, toki C# boshqa yo’nalishga o’tmaguniga qadar. Shundan so’ng C# kompyuter uchun dasturlar ishlab chiqarish bo’yicha xalqaro standart sifatida tasdiqlandi va umumiy til infrastrukturasi bilan ishlatiladi.

C# ning juda ko’p versiyalari mavjud, ularning barchasi dasturiy ta’minotga yanada ko’proq yangilanishlar kiritdi

1-versiya oddiy, ko’p maqsadli umumiy dasturlash tili sifatida ishlab chiqarilgan.&#x20;

2-versiya 2005-yilda ishlab chiqarilgan. Bir vaqtning o’zida ma’lumotlarning katta qismini ko’rib chiqishga imkon beruvchi iteratorlardan foydalanish imkoniyatlarini o’z ichiga oldi.

3-versiya 2007-yilda ishlab chiqilgan. Yangi iboralar (kodlar) yaratildi; Aynan ushbu versiyasidan boshlab C# Java tiliga qaraganda trendda yuqori o’rinlarni egallay boshladi.

![](/files/-MLcyOh7VQR_FoD5M32f)

4-versiya 2010-yilda ishlab chiqildi. Mutaxassislar Interlop turlarini va dinamik kalit so’zlari yaratdi va boshqa tillarda bo’lmagan nafislikni berdi.

5-versiya 2012-yilda ishlab chiqilgan. Asinkronizatsiyalash imkoniyati paydo bo'ldi.

6-versiya 2013-yilda ishlab chiqarilgan. Yangi filtrlar va initsializatorni taqdim etdi Kod yozish avvalgidan ham osonlashdi.

7-versiya 2017-yilda ishlab chiqarilgan. Yangidan yangi imkoniyatlar, xususan .NET Core va operatsion tizimlardan foydalanish imkoniyatlariga ega bo’ldi.


# Kirish

Suxrob Xayitmurodov

Dasturchi sifatida bizni tanlaganingizdan juda xursandmiz (mendan tashqari yana bir nechta maqolalar tayyorlagan akalarim ham). Ushbu darsdan boshlab siz C# tilini o’rganishni boshlaysiz!!!

## C# tilida nimalar qilsa bo'ladi, to'liq ma'lumot bering?!

Mobil dasturlar\
O'yinlar (kompyuter/mobil)\
Desktop dasturlar\
Ma'lumotlar bazasi uchun dasturlar\
Veb dasturlar\
Veb servislar\
VR - Virtual Reality uchun dasturlar\
Veb saytlar

## Nimada boshlashim mumkin?

Birinchi qiladigan vazifamiz kod yozish uchun muhit yuklab olish va uni o’rnatish hisoblanadi. Chunki muhitsiz siz hech narsa qila olmaysiz. Bizga kerak bo’lgan muhit esa Visual Studio 2019 nomli editor.\
Uni bu yerdan topasiz:\
Windows: <https://visualstudio.microsoft.com/vs/preview/>\
Mac:<https://docs.microsoft.com/en-us/visualstudio/releasenotes/vs2019-mac-relnotes>

![](/files/-Mcz9TFu1EgnerxJ1zCd)

Qizil chiziq ichidagi knopkani bosasiz. So’ngra fayllar orasidan installation (o’rnatuvchi dasturini) topib **Run as administrator** ni bosib, ishga tushirasiz.

![](/files/-MLrjqT3glHbQotjnxjp)

![Litsenziya shartlarini qabul qilasiz](/files/-MLrjzs9hSKojVZ-WsMs)

![Va o'rnatishni boshlaydi...](/files/-MLrkEK4cih_BW2ErAwK)

![So’ngra biz .NET Desktop Development ni tanlaymiz va to’liq o’rnatamiz.](/files/-MLrksD7WUAxx2T3SQ3D)

![Yuqoridagi rasmda esa siz o’zingizga mos bo’lgan tilni tanlashingiz mumkin. Menda Ingliz tili!](/files/-MLrlDRccdoumfy5X3jr)

## Muharrirda new project/новый проект hosil qilish!

![Qizil rangli chiziq ichidagi knopkani bosasiz. So’ng belgilangan tartibda sozlamalarni to’g’irlab chiqasiz.](/files/-MLrm49gKdqEHDXNmW9z)

![Shundan so’ng Next ni bosamiz va quyidagicha natija ekranga uzatiladi:](/files/-MLrmKzGvwpNnOvodUAZ)

![Birinchi strelka yaratmoqchi bo’lgan faylingizning nomi hisoblanadi, buni xohlagancha nomlashingiz mumkin. Ikkinchi strelkada esa faylingizni kompyuterning qaysi fayl ichiga joylayotganini ko’rsatgan. Uchinchi strelkada esa .NET Frameworkining oxirgi versiyasi ko’rsatilgan. Rasmda ko’rsatilgan versiyasi esa oxirgi versiya hisoblanadi va men ham aynan ushbu versiyasini ishlatishni maslahat beraman. Chunki avvalgi versiyalariga qaraganda ko’proq imkoniyatlariga ega.](/files/-MLrmt3HrvvsafUboxU7)

![Ana endi Visual Studio 2019 to’liq o’rnatildi va ko’rib turganingizdek ishlayapti!](/files/-MLrn1N14bJfDw2WPGlR)

```csharp
Console.WriteLine("E'tiboringiz uchun atdushi raxmat!:)))");
```


# Visual Studio 2019

Suxrob Xayitmurodov

Ushbu maqolada sizga Visual Studio 2019 matn muharriri bilan tanishtirib chiqaman!

Oldingi maqolam uni qanday yuklab olish va o’rnatish haqida edi, bu maqola esa uni qanday ishlatish haqida

Ushbu muharrir kompilyatorlarni, kodlarni to’ldirish uchun muhitlarni va yana ko’plab hususiyatlarni o’z ichiga oladi. Bundan tashqari ushbu muharrirda ko’pgina grafik dizaynlar qilsak ham bo’ladi (kompyuter va mobil dasturlar dizayni).

## Boshladik unda!!!

![](/files/-MLroFlzBhlEKzmBiffs)

* Create a new project – yangi fayl yaratish.
* Run your code – kodingizni ishga tushirish.
* Launch Live Share – Ijtimoiy tarmoqlarda jonli efir qilish.
* Send feedback – Mulohazalar yuborish (qo’shimcha fikrlar bildirish).
* Add control to your UI – UI dizayningizni nazorat qilish.
* Manage files, projects, solutions – Fayllar, Loyihalar, Mashqlarni boshqarish.
* Collaborate on code projects with your team – Jamoa bilan kod loyihalarda ishlash.
* Manage your Azure resources – Azure resurslaringizni boshqaring.

![Bu rasmda sizga barcha resurslar ko’rsatilgan:](/files/-MLrpSlYBUOs6xlDNE8j)

1. Solution Explorer – Bu sizga kod fayllarini ko’rish, navigatsiya qilish va boshqarish imkonini beradi. Bundan tashqari siz bu menyu orqali kodingizni tartibga solishingiz mumkin.
2. The Editor Window – Bu joyda siz kodlashingiz, dasturingizni dizaynini chizishingiz mumkin (bu yerda u Program.cs deb nomlangan).
3. Team Explorer – Bunda Git va TFVC platormalarida loyihalar bilan tanishish va boshqalar bilan loyihangizni baham ko’rish imkonini beradi

### Qolgan parametrlarni keyinchalik o'zingiz kod yozish mobaynida bilib boraverasiz, ularni tushuntirib o'tirishga hojat ham yo'q, barchasi oddiy va elementer funksiyalar!

> E'tiboringiz uchun raxmat!!!:)))


# O'zgaruvchilar

Abduxoshimov Hondamir

Barcha dasturlash tillarida eng ahamiyatli o’rinlardan birida turadigan, hamda ko’pchilikka ilk dasturlashni boshlash chog’larida muammo bo’lishga ulgurgan, ushbu mavzu to’g’risida yaqin daqiqalar ichida tushunmovchiliklarga barham beramiz. Kitobiy gaplardan boshlaganimga e’tibor bermasligingizni so'rayman, kompyuter qarshisida ko’p o’tirishning oqibati shunaqa bo’larkan. Hop endi mavzuga qaytamiz. O’zgaruvchi - bu turli xil ko’rinishdagi ma’lumotlarni o’zida saqlab turuvchi va dastur ishlash davomida qiymati o’zgarib boradigan konteyndir. Tushunish qiyin bo’lganduraa? Kayfiyatni cho’ktirmaymiz. Keling berilgan iboraga, hayotiy misol orqali o’xshatish berib ko’ramiz: Tasavvur qiling sizning uyingizda omborxona bor. Tabiiyki u yerda , kundalik yumushlaringizda foydalanadigan ishchi qurollar (ketmon, lapatka...) va oyingiz tayyorlagan kampot-u qiyomlar saqlanadi. Kampot shirin bo’lganidan yozning jazirama issig’ida zo’r ketadi va ombor ham asta-sekinlik bilan bo’shashni boshlaydi. Lekin omborga kirib, uni ochmaguningizgacha qishin – yozin turaveradi. O’zgaruvchilar ham bir ombor hisoblanadi. Ular ham o’zida ma’lum bir toifaga oid qiymatlarni saqlab boradi.

O’zgaruvchilarni e’lon qilish. O’zgaruvchilarni e’lon qilish uchun birinchi navbatda uning qaysi toifaga tegishliligi, uning nomi hamda unga beriladigan qiymatlarni aytib qo’yish talab etiladi.

**Tip o’zgaruvchi\_nomi = qiymati**

Tip deyilganda – int , string , double kabilar nazarda tutildi. O’zgaruvchilarni e’lon qilish to’g’risida gap ochilganda maktablardagi bir holat ko’zimning oldiga kelaveradi:

Ustoz: - Kimning bolasisan ?\
O’quvchi: – Direktorni.\
Ustoz: - O’tir bahoying besh!\
Ustoz: - Senchi ?\
O’quvchi: - Kirakashni.\
Ustoz: - O’tir bahoying uch!

**Otaning\_kasbi farzand = baho**

Albatta bu hazil 😊 Quyida bir necha toifaga mansub bo’lgan o’zgaruvchilarni e’lon qilishni ko’rishimiz mumkin: string toifasiga mansub o’zida “Mening Dasturim” satrni saqlab turuvchi project o’zgaruvchisini e’lon qilish:

```csharp
using System;
namespace MyProgram
{
    static void Main(string[] args)
    {
        string project = “Mening Dasturim”;		
        Console.WriteLine(project);	
    }
}
```

Natija: Mening dasturim

int tipiga oid x o’zgaruvchisini e’lon qilish va unga 5 qiymatini o’zlashtirish

```csharp
using System;
namespace MyProgram
{
    static void Main(string[] args)
    {
        int x = 5;
	Console.WriteLine(x);
    }
}
```

Natija: 5

Eslatma: Agarda o’zgaruvchiga yangi qiymat o’zlashtirilsa, uning eski qiymati yo’qolib o’rniga yangi qiymat saqlanadi.

```csharp
namespace MyProgram
{
    static void Main(string[] args)
    {
	int x= 5;
        x = 20; // x dagi qiymat endi 20
	Console.WriteLine(x);
    }
}
```

O’zgaruvchilarni qurishda ingliz alifbosidagi harflar, raqamlar hamda tag chiziqdan foydalanishimiz mumkin (m.u., myVariable, \_myVariable).z

Eslatma: O’zgaruvchilarni nomlashda tushunarli va eslab qolish osonroq bo’lgan nomlardan foydalanish tavsiya etiladi.


# Ma'lumot turlari

Abduxoshimov Xondamir

Ma’lumotlar toifasi – bu o’zgaruvchilarning turi va xotiradan qancha joy egallashini belgilab beruvchi kerakli omil. Foydalanilgan o’zgaruvchiga to’g’ri tipni belgilash muhim vazifalardan biridir. Sababi bu orqali biz, yaratayotgan dasturimizda yuzaga keladigan ba’zi bir muammolarni oldini olishimiz, eng asosiysi vaqt tejalishi va dasturning xotiradan kamroq joy egallanishiga erishishimiz mumkin. C# dasturlash tili keng ko’lamdagi ma’lumotlar toifasini o’zida mujassamlashtirgan.\
Quyida bir nechta ma’lumotlar toifasiga birikkan holatda o’zgaruvchilarni hosil qilishni ko’rishimiz mumkin:

```csharp
string stringVar = "Salom Dunyo!!";
int intVar = 100;
float floatVar = 10.2f;
char charVar = 'A';
bool boolVar = true;
```

C# da ma’lumotlar toifasi asosan 2 turli bo’ladi: qiymatli(value) va ma’lumotli(reference). Value turdagi toifalarga – odatiy tiplar(sonli(int , float, double…), mantiqiy(bool), belgili(char) va matnli(string)) , enum turlari va strukturalar kabilar kiradi . Reference turdagi toifalar o’z ichiga – classlar, interfeys, delegatlar hamda massiv turlarini oladi.

![Klassifikatsiya](/files/-MLYDWINw_DiT3RaLUpd)

C# da oldindan tashkil qilingan bir qancha tiplar mavjud. Quyidagi jadvalda ulardan ba’zilarini ko’rishimiz mumkin.

![](/files/-MLYDlBjctWjQD_NUVdl)

![](/files/-MLYDpR0HETmmD7HNwUC)

```csharp
// compile time error: Cannot implicitly convert type 'long' to 'int'.
int i = 21474836470
```

### Sonli tiplar

Sonli tiplar o’z o’rnida ikki turga bo’linadi: butun(integer) va haqiqiy(floating point). Butun tiplar – barcha butun, musbat va manfiy (52, -52, 0) sonlarni o’zi ichiga oladi. Bularga misol tariqasida – byte, short , int , long , int32, int64 larni olishimiz mumkin. Haqiqiy tiplar – o’zlarida kasr(1.2, -2.3, 10.5) sonlarni aks ettiradi. Misol uchun : float, double, long double kabi tiplar. C# dasturlash tilida sonli tiplar ko’p bo’lishiga qaramay, int(butun) va double(haqiqiy) tiplari ko’proq foydalaniladi. Quyidagi ko’rinishda sonli tiplarga doir toifalarni ko’rishimiz mumkin.

![](/files/-MLYE3QYxmwFLtWWQ-YB)

### Butun tiplar

Butun tiplar – barcha musbat va mandiy butun sonlarni o’z ichiga oladi. C# da butun tiplar oilasida 4 ta tip mavjud: *byte,* *short*, *int* , *long*. Byte byte tipi 0 dan 255 gacha bo’lgan sonlarni qabul qiladi, xotiradan 8 bitni egallaydi hamda Byte strukturasiga tegishlidur\
sbyte tipi ham byte tipi bilan bir xil , lekin u -128 dan 127 gacha manfiy sonlarni ham o’zida saqlaydi. sbyte – *Sbyte* strukturasidan o’rin olgan .

```csharp
byte b1 = 255;
byte b2 = -128;// compile-time error: Constant value '-128' cannot be converted to a 'byte'
sbyte sb1 = -128; 
sbyte sb2 = 127; 

Console.WriteLine(Byte.MaxValue);//255
Console.WriteLine(Byte.MinValue);//0
Console.WriteLine(SByte.MaxValue);//127
Console.WriteLine(SByte.MinValue);//-128

```

***Short***\
short tipi -32,768 dan 32,767 gacha bo’lgan sonlarni o’zida jamlaydi, xotiradan egallanadigan joy 16 bit. Int16 stukturasini ichida joylashgan. short tipiga o’xshash ushort tipi ham mavjud. Bu tip 0 dan 65,535 gacha sonlarni qabul qiladi. UInt16 strukturasida joylashgan.

```csharp
short s1 = -32768;
short s2 = 32767;
short s3 = 35000;//Compile-time error: Constant value '35000' cannot be converted to a 'short'

ushort us1 = 65535;
ushort us2 = -32000; //Compile-time error: Constant value '-32000' cannot be converted to a 'ushort'

Console.WriteLine(Int16.MaxValue);//32767
Console.WriteLine(Int16.MinValue);//-32768
Console.WriteLine(UInt16.MaxValue);//65535
Console.WriteLine(UInt16.MinValue);//0
```

***Int***\
int tipi 32 bitlik butun toifadur. Butun sonlarni qabul qilish chegarasi -2,147,483,648 dan 2,147,483,647 gacha. Int32 strukturasida joylashgan. Bu tipga yaqin tip uint tipi. UInt32 strukturasiga tegishli bo’lib 0 dan 4,294,967,295 gacha sonlarni o’z ichiga oladi.

```csharp
int i = -2147483648;
int j = 2147483647;
int k = 4294967295; //Compile-time error: Cannot implicitly convert type 'uint' to 'int'.

uint ui1 = 4294967295;
uint ui2 =-1; //Compile-time error: Constant value '-1' cannot be converted to a 'uint'

Console.WriteLine(Int32.MaxValue);//2147483647
Console.WriteLine(Int32.MinValue);//-2147483648
Console.WriteLine(UInt32.MaxValue);//4294967295
Console.WriteLine(UInt32.MinValue);//0
```

int toifasi o’n oltilik va ikkilik sanoq sistemalariga nisbatan ham foydalaniladi. O’n oltilik sanoq sistemalari 0x yoki 0X qo’shimchalari bilan, ikkilikdagi sonlar esa, 0b yoki 0B bilan boshlanadi.

```csharp
int hex = 0x2F;
int binary = 0b_0010_1111;

Console.WriteLine(hex);
Console.WriteLine(binary);
```

***Long***\
long tipi o’zida -9,223,372,036,854,775,808 dan 9,223,372,036,854,775,807 gacha sonlarni saqlaydi. Xotiradan egallaydigan joyi 64 bitni tashkil etadi. Int64 strukturasida joylashgan. ulong tipi ham long tipi bilan o’xshash. U o’zida 0 dan 18,446,744,073,709,551,615 gacha sonlarni qabul qiladi. Int64 strukturasida joylashgan.

```csharp
long l1 = -9223372036854775808;
long l2 = 9223372036854775807;

ulong ul1 = 18223372036854775808ul;
ulong ul2 = 18223372036854775808UL;

Console.WriteLine(Int64.MaxValue);//9223372036854775807
Console.WriteLine(Int64.MinValue);//-9223372036854775808
Console.WriteLine(UInt64.MaxValue);//18446744073709551615
Console.WriteLine(UInt64.MinValue);//0
```

### Haqiqiy tiplar

Haqiqiy toifalar o’zida musbat va manfiy o’nli kasrlarni aks ettiradi. C# da haqiqiy toifalar asosan 3 turli: float, double va decimal\
\
***Float***\
float tipi xotiradan 4 baytni egallaydi. Single strukturasiga tegishli. float toifadagi tipni hosil qilish uchun f yoki F suffiksidan foydalaniladi.

```csharp
float f1 = 123456.5F;
float f2 = 1.123456f;

Console.WriteLine(f1);//123456.5
Console.WriteLine(f2);//1.123456
```

***Double***\
double tipi float tipiga qaraganda imkoniyati kattaroq, lekin xotiradan 8 bayt egallaydi. Double strukturasida joylashgan. double toifadagi tipni hosil qilish uchun d yoki D suffiksidan foydalaniladi.

```csharp
double d1 = 12345678912345.5d;
double d2 = 1.123456789123456D;

Console.WriteLine(d1);//12345678912345.5
Console.WriteLine(d2);//1.123456789123456
```

***Decimal***\
decimal tipi xotiradan boshqa tiplarga qaraganda balandroq joy egallaydi. Egallanadigan joy 16 bayt. Bu tip asosan moliya sohalaridagi dasturlarda ko’proq foydalaniladi. decimal toifadagi tipni hosil qilish uchun m yoki M suffiksidan foydalaniladi.

```csharp
decimal d1 = 123456789123456789123456789.5m;
decimal d2 = 1.1234567891345679123456789123m;

Console.WriteLine(d1);
Console.WriteLine(d2);
```


# Operatorlar

Suxrob Xayitmurodov

Bu maqolamda men operatorlar haqida qisman ma'lumot berib o'taman.

Operatorlar odatda harakat yoki jarayonni (harakat va jarayonni ham bo’lishi mumkin) ifodalovchi belgidir. Ular matematika va logikani yaxshi biladigan har qanday inson uchun muammo tug’dirmaydi. Ya’ni ularning asosini aynan shular tashkil qiladi. Operatorlar ma’lum bir qiymat yoki operandlarni boshqarishga qodir bo’ladi. Operatorlar har qanday dasturlash tilining asosini tashkil qiladi. Ular oddiy hisoblashlardan tortib, hattoki xavsizlikni shifrlash kabi murakkab algoritmik vazifalarni ham bajara oladi!

### C# dasturlash tilida operatorlar nechta?

Asosan 6 xil turi mavjud:

* Arifmetik operatorlar
* Mantiqiy operatorlar
* Shart operatorlari
* Tanlash operatorlari
* Takrorlash operatorlari
* O'tish operatorlari

### Ular haqida qisman ma'lumot beraman degan edingiz!?

1. Arifmetik operatorlar bizga arifmetik amallar qilish imkonini beradi. Ya’ni biz bunda 5 arifmetik amallarni bajara olamiz.

```csharp
int result; 
int x = 10, y = 5; 
              
    // Addition 
    result = (x + y); 
    Console.WriteLine("Addition Operator: " + result); 
              
    // Subtraction 
    result = (x - y); 
    Console.WriteLine("Subtraction Operator: " + result); 
```

2\. Mantiqiy operatorlarda biz mantiqiy amallar ustida ishlaymiz. Agar qiymat to’g’ri bo’lsa true aks holda false qiymatini qaytaradi.

```csharp
int x = 5, y = 10, result; 
              
  // To find which value is greater 
  // Using Conditional Operator 
  result = x > y ? x : y;  
              
  // To display the result  
  Console.WriteLine("Result: " + result); 
           
  // To find which value is smaller 
  // Using Conditional Operator 
  result = x < y ? x : y;  
              
  // To display the result 
  Console.WriteLine("Result: " + result); 
```

3\. Qachonki e’lon qilingan bir qancha qiymatlar bo’lsa, ushbu operator o’ziga mos qiymatni tanlashda va uni amalga oshirishda ishlatiladi

```csharp
int day = 2;
switch(day) 
{
    case 1:
	Console.WriteLine(“Monday”);
	break;
    case 2:
	Console.WriteLine(“Tuesday”);
	break;
    default:
	Console.WriteLine(“Wrong day!”);
	break;
}
```

{% hint style="info" %}
Agarda ushbu ma'lumotlar sizga tushunarli bo'lgan bo'lsa bundan men xursandman. Agarda ularni eslab qolgan bo'lsangiz men juda ham xursandman.\
Agarda tushunmagan bo'lsangiz kuyinmang, ushbu operatorlar bilan hali maqolalarimizda batafsil tanishib olasiz
{% endhint %}


# Kalit so'zlar

Abdulaziz Abduxalil-zoda

Kalit so'zlar kompilyator uchun maxsus ma'nolarga ega bo'lgan oldindan belgilangan, zaxiralangan identifikatorlardir. Ular @ prefiksisiz dasturlarda identifikator sifatida ishlatilishi mumkin emas. Masalan, @if haqiqiy identifikator hisoblanadi, lekin if emas chunki bu kalit so'z bo'ladi. Ushbu maqoladagi birinchi jadvalda C# dasturining biron bir qismida identifikator sifatida ishlatib bo'lmaydigan kalit so'zlar keltirilgan. Ushbu maqoladagi ikkinchi jadvalda kontekstli C# kalit so'zlari keltirilgan. Kontekstli kalit so'zlar faqat ma'lum bir dastur kontekstida ishlatish mumkin va bu kontekstdan tashqarida identifikator sifatida foydalanish mumkin. Odatda, oldingi versiyalarda yaratilgan dasturlarni buzmaslik uchun yangi kalit so'zlar kontekstli kalit so'zlar sifatida C# tiliga qo'shiladi.

**abstract as base bool break byte case catch char checked class const continue decimal default delegate do double else enum event explicit extern false finally fixed float for foreach goto if implicit in int interface internal is lock long namespace new null object operator out override params private protected public readonly ref return sbyte sealed short sizeof stackalloc static string struct switch this throw true try typeof uint ulong unchecked unsafe ushort using virtual void volatile while**

*Kontekstli kalit so'zlar***:**

&#x20;Kontekst kalit so'zi kodning o'ziga xos ma'nosini ta'minlash uchun ishlatiladi, ammo bu C# -da saqlangan so'z emas. partial va where kabi ba'zi bir kontekstli kalit so'zlar ikki yoki undan ortiq kontekstda maxsus ma'nolarga ega.

**add alias ascending async await by descending dynamic equals from get global group into join let nameof notnull on orderby partial (tur) partial (metod) remove select set unmanaged value var when where yield**


# ReadLine

Ra'no Norpo'latova

Assalomu aleykum bo'lajak .NET dasturchilar, ushbu mavzuda sizlarga nimalardir tushintirishga harakat qilaman, tushunmasangiz menda emas :) xaxaa

`Console.WriteLine()` malumotlarni chiqarish, chop etish (output) uchun foydalaniladi. Endi belgilar oqimini o'qish uchun (input) `Console.ReadLine()` dan foydalanamiz. `ReadLine()` metodi (funksiyasi) `Console` sinfi ga tegishli.

```csharp
using System;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            string ism;
            Console.WriteLine("Ismingizni kiriting: ");
            //string tipida qiymat qaytadi
            ism = Console.ReadLine();
        }
    }
}
```

`Console.ReadLine()` bilan ma'lumotlarni faqat string tipida olishimiz mumkin. Masalan int tipida son kiritmoqchi bo'lsak uni string tipidan int tipiga (o'zgartirishimiz) konvertatsiya qilishimiz kerak. Bunda `Convert` sinfining `ToInt32()` metodi yoki `int` sinfining `Parse()` metodidan foydalanashimiz mumkin!

```csharp
using System;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            string ism;
            int yosh;
            Console.Write("Ismingizni kiriting: ");
            //string tipidagi qiymat qaytadi
            ism = Console.ReadLine();

            Console.Write("Yoshingizni kiriting: ");
            //string turidan int turiga aylantiriladi 
            yosh = Convert.ToInt32(Console.ReadLine());
            //int.Parse yordamida convertatasiya qilamiz
            //yosh = int.Parse(Console.ReadLine());   
        }
    }
}
```

Convertatsiyani ikki xil usulini ikki sonning yig’indisi (a+b) da ko’rib chiqamiz.

```csharp
namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            int a, b;
            a = Convert.ToInt32(Console.ReadLine());
            b = int.Parse(Console.ReadLine());
            Console.WriteLine("Natija: " + (a + b));
        }
    }
} 
```

`Parse()` metodidan foydalanishni maslahat beramiz. Har bir tur (int, long, double...) ushbu metodni o'z ichiga oladi. Ya'ni string turidan o'sha joriy turga o'girish uchun foydalaniladi

{% hint style="info" %}
Ma'lumot o'rnida aytib o'tish lozimki, `Console` sinfi, ekrandan ma'lumot o'qib oladigan 3 ta metodni o'z ichiga oladi.`Read(), ReadLine(), ReadKey()`
{% endhint %}

* ReadKey() - Biror klavish bosilishini kutadi va uning kodini qaytaradi (ConsoleKeyInfo turida)
* Read() - Bir belgi kiritilishi kutiladi va o'sha belgining ASCII kodi qaytariladi (int turida)
* ReadLine() - Satr kiritilishi kutiladi va string turida qaytaradi.

**Boshida ozroq tushinarsiz bo'lishligi mumkin, lekin tezda o'rganib ketasiz :)**


# If-else

Sobirjonov O'tkirbek

C# dasturlash tilida if-else lar bilan tanishamiz (Men tanishman siz tanishasiz) Biz hayotda juda ko’p if va else ni ishlatganmiz. “IF” so’zi o’zbek tiliga “Agar”\
deb tarjima qilinadi. Keling avval ifni o’zini o’rganib olaylik : Misol: “Agar bir qop pulim bo’lsa, albatta ularni hammasini yoqib yuborgan bo’lar edim”. Bu so’zda biz if ni o’zidan foydalandik demak keling uni C# dasturlash tilida ko’ramiz.

```csharp
using System;
namespace MyProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            bool meningBirQopPulim = false;
            if(meningBirQopPulim == true)
            {
                //Yoqib yuborgan bo'lar edim
            }
        }
    }
}

```

Demak Bu dasturda meningBirQopPulim degan o’zgaruvchi e’lon qildim, va bir qop\
pulim yo’qligi uchun false qiymat berdim. Endi esa ifga o’tamiz Dasturda avval “if” kalit so’zi yozib keyin qavslar orasiga shart beriladi, bu shart mantiqiy amallardan bolishi kerak ya’ni true yoki false qiymat qaytaradigan. Shuning uchun qavslar ichiga (birQopPulim == true) deb shart berdik, va bilib turganingizdek yolg’on yani false qiymat qaytaradi. Va shart bajarilmaydi. Natijada jingalak qavslar ichidagi codlar ish bajarmaydi. Endi bu Codelarni bizor o’zgartirsak, ya’ni meni biroz boyitsak

```csharp
using System;
namespace MyProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            bool meningBirQopPulim = true;
            if(meningBirQopPulim == true)
            {
                Console.WriteLine("Yoqib yuborish kerak");
            }
        }
    }
}

```

Bu dasturda men men o’zimni bir qop pulim bor deb e’lon qildim va Dastur shartni tekshirib ko’radi e’tibor bering (true) qiymatga aylanayapti. Va natijada Console oynaga “yoqib yuborish kerak” degan satr chiqadi. Keling endi else ni ham ishlatamiz avval codeni bir ko’ring va ozroq fikr Yuritingchi.

```csharp
using System;
namespace MyProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            bool meningBirQopPulim = true;
            if(meningBirQopPulim == true)
            {
                Console.WriteLine("Yoqib yuborish kerak");
            }
            else
            {
                Console.WriteLine("Tushingni borib suvga ayt!");
            }
        }
    }
}
```

Bu dasturda siz if-else ni strukturasini ko’rdingiz Bu structuraga dastur

![Mana sizga tushuntirish)))](/files/-MLT01KJKyOZ2ztC9qUo)

Shunday qaraydi demak shart true bolsa chap tarafga false bo’lsa o’ng tarafga qarab ketadi. Bu yerda algoritm tarmoqlanayapti shundaymi. Yuqorida siz fikrlagan dastur natijasida Console oynaga “yoqib yuborish” kerak degan yozuv chiqadi yana bir qarang va fikrlab ko’ring. Hullas If kalit so’zidan keyin kelgan shart true bo’lsa if ning ichidagi jingalak qavslar ichidagi kod bajariladi, false bo’lsa else ning ichidagi jingalak qavslar ichidagi kod bajariladi. Hozir yozgan codelarimizni Jamlasak:

```csharp
using System;
namespace MyProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            bool meningBirQopPulim = false;
            if(meningBirQopPulim)
            {
                Console.WriteLine("Yoqib yuborish kerak");
            }
            else
            {
                Console.WriteLine("Tushingni borib suvga ayt!");
            }
        }
    }
}
```

Natijada Console oynaga “Tushingni borib suvga ayt” degan so’z chiqadi. Sababi meningBirQopPulim o’zgaruvchi false qiymat oldi shuning uchun if shartidaga shu o’zgaruvchi nomi yetarli chunki o’zi false qiymat qaytarib turibdi. Yanada yaxshiroq tushunishingiz uchun bir nechta dasturlar ko’rsataman:

```csharp
using System;
namespace MyProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            int getNumber = 0;
            if(getNumber == 0)
            {
                Console.WriteLine("Rost");
            }
            else
            {
                Console.WriteLine("Yolg'on")
            }
        }
    }
}

```

Natija: "Rost"

! Agar if yoki else ning operatori bitta bolsa jingalak qavslar shart emas!(qoyilsa ham qoyilmasa ham to’g’ri)

```csharp
using System;
namespace MyProgram
{
    class Program
    {
        static void Main(string[] args)
        {
            int DunyoMojizalari = 6;
            if (DunyoMojizalari == 7) Console.WriteLine("Hammasi joyida");
            else if (DunyoMojizalari < 7)
            {
                Console.WriteLine("Mo'jizalarda Kamchilik bor");
                Console.WriteLine("Aslida 7 ta bo'lish kerak edi");
            }
            else Console.WriteLine("Ko'payib ketdi");
        }
    }
}

```

Natija: Mo'jizalarda Kamchilik bor Aslida 7 ta bo'lish kerak edi Agar bu yerda qavslarni qo’ymaganimizda edi natija: “Mo'jizalarda Kamchilik bor” degan so’z chiqardi.


# Switch

Suxrob Xayitmurodov

## Tanlash Operatori

Bu maqolamda men sizga tanlash operatorini tushuntirib beraman!

Tanlash operatori bizga bir nechta qiymatlardan, o’zgaruvchilarga to’g’ri keluvchi qiymatni tanlashda va uni ishga tushirishda ishlatiladi. Misol uchun hafta kunlarini raqamidan topish topshiriq sifatida berildi. Ularni bemalol topishimiz mumkin, lekin kompyuterga uni qanday tushuntiramiz? Buni bilish uchun ushbu maqolamni o’qib chiqishingizni tavsiya qilaman

### Sintaksis

```csharp
switch (<o'zgaruvchi>)
{
    case <o'zgarmas ifoda1> : <operator 1>; break;
    case <o'zgarmas ifoda2> : <operator 2>; break;
    ...
    case <o'zgarmas ifodaN> : <operator N>; break;
    default : operator N + 1; break;
}
```

**switch** kalit so’zini yozganimizdan so’ng qavslar ichiga biror-bir o’zgaruvchini kiritishimiz zarur shundan so’ng jingalak qavslar ochamiz va tanlash maqsadida **case** kalit so’zlarini kiritamiz va undan so’ng ifodamizni kiritamiz va uni nima vazifa bajarishini operatorlar yordamida yozishimiz kerak bo’ladi, bir nechta (siz xohlagancha) qiymatlar berilgandan so’ng o’zgaruvchiga to’g’ri kelmaydigan qiymat lar ham berilishi mumkin, bunday holatlarda **default** kalit so’zidan foydalangan holda operatorlarni kiritib tanlash operatorimizga yakun yasaymiz!!!

### Masala

\
Har bir hafta kunlarining raqamiga moslab ularni biriktirib qo’ying, aks holda “Bugun ahvollar joyidami og’ayni???” degan javob qaytarilsin.

```csharp
int n;

Console.Write("Hafta kunini kiriting = ");

n = int.Parse(Console.ReadLine());

switch (n)
{
    case 1: 
      Console.WriteLine("Dushanba"); break;
    case 2: 
      Console.WriteLine("Seshanba"); break;
    case 3: 
      Console.WriteLine("Chorshanba"); break;
    case 4: 
      Console.WriteLine("Payshanba"); break;
    case 5: 
      Console.WriteLine("Juma"); break;
    case 6: 
      Console.WriteLine("Shanba"); break;
    case 7: 
      Console.WriteLine("Yakshanba"); break;
    default: 
      Console.WriteLine("Bugun ahvollar joyidami og'ayni???"); 		  break;
}
```

**default** - Odatda case ichida e'lon qilinmagan ifodaga nisbatan qo'llaniladi. Ya'ni agarda case ichidagi ifoda uchun mos kelmasa, C# odatiy operatorlarni ishga tushiradi. (Xullas kiritilgan qiymatlardan bittasi ham to'g'ri kelmasa, default da berilgan qiymatni qabul qiladi)

**break** - Ma'lum bir ifodaga tegishli operatordan keyin qo'yiladigan kalit so'z. C# tili e'lon qilingan operatorni ishga tushirgandan so'ng, u ushbu so'zni o'qiydi va kodni to'xtatadi. Agarda u mavjud bo'lmasa, undan keyingi operatorni ham bajarib logik xatolikka yo'l qo'yishi mumkin!

{% hint style="info" %}
Boshqa dasturlash tillaridan farqli ularoq, C# tilida **default** operatoridan so'ng ham **break** ishlatishimiz lozim!!!
{% endhint %}


# Math sinfi

Mamataliyev Diyorbek

Assalomu alaykum, yosh dasturchilar. Dasturlashni o'rganar ekansiz, matematikaga ishingiz tushishi tabiiy hol. Aytaylik, dasturingizda biror formula yoki ifodaning qiymatini hisoblashga to'g'ri kelib qolishi mumkin. Xo'sh, bu holatlarda matematik ifodalarni dastur kodiga qanday kiritamiz? Ifoda ichida qo'shish (+), ayirish (-), ko'paytirish (`*`), bo'lish (/), qoldiqli bo'lish(%) dan tashqari boshqa amallar qatnashgan bo'lsa, qo'shimcha metodlardan foydalanishga to'g'ri keladi. Buning uchun bizga **Math** sinfi metodlari yordam beradi. Bu metodlarni chaqirish uchun **Math** so'zidan keyin nuqta qo'yib, metod nomini yozamiz. Metod turiga qarab bir yoki bir nechta qiymatni kiritganimizda bizga hisoblangan qiymatni qaytaradi. Masalan, **Math.Abs(-3.5)** metodi 3.5 ni qaytaradi. Endi esa, sizga ko'proq **Math** sinfi metodlarini tanishtirishga harakat qilaman.

**Math.Abs()** – sonning absolyut qiymati (moduli) ni hisoblaydi. Kiruvchi parametr sifatida kiritilgan bitta son ixtiyoriy sonli tipda bo'lishi mumkin, faqat 2^64 dan katta bo'lib ketmasligi kerak. Qaysi tipda (*double, decimal, long, int, ..*) qiymat kiritilgan bo'lsa qaytarilgan qiymat ham shu tipda bo'ladi.

**Math.Acos()** – sonning arkkosinusini hisoblaydi. Kiruvchi va chiquvchi parametrlar faqat *double* tipida bo'ladi. Qaytarilgan burchak qiymati radianda ifodalangan bo'ladi. Math.Acos(0)=1,5707963267948966.

**Math.Asin()** – sonning arksinusini hisoblaydi. Kiruvchi va chiquvchi parametrlar *double* tipida bo'ladi. Qaytarilgan burchak qiymati radianlarda ifodalanadi. Math.Asin(1)=1,5707963267948966.

**Math.Atan()** – sonning arktangensini hisoblaydi. *double* tipida ma'lumot qabul qiladi va qaytaradi. Qaytarilgan burchak qiymati radianlarda ifodalangan bo'ladi. Math.Atan(1)=0,7853981633974483.

**Math.BigMul()** – ikki butun sonning ko’paytmasini hisoblaydi. *int* yoki *long* tipida ma'lumot qabul qiladi. *long* tipida qiymat qaytaradi. Masalan, Math.Bigmul(3,4)=12;

**Math.Cbrt()** - kiritilgan sonning kub ildizini hisoblaydi. *double* tipida qiymat qabul qiladi va qaytaradi. Masalan, Math.Cbrt(27) ifoda bizga 3 ni qaytaradi.

**Math.Ceiling()** – sonni ortig'i bilan yaxlitlaydi. Kiritilgan sondan katta yoki unga teng bo'lgan eng yaqin butun sonni qaytaradi. *double* yoki *decimal* tipida ma'lumot qabul qiladi va qaytaradi. Math.Ceiling(3.14)=4, Math.Ceiling(6.0)=6; Math.Ceiling(-4.3)=-4;

**Math.Cos()** – burchakning kosinusini hisoblaydi. Burchak qiymati radianda kiritiladi. Kiruvchi va qaytariluvchi parametrlar faqat *double* tipida bo'ladi. Math.Cos(3.141592653589793)=-1;

Keling, bu metodlarning qanday ishlashini ko'rish uchun kiritilgan sonning sinusini va kosinusini hisoblaydigan dastur yozib ko'ramiz:

```csharp
using System;
class Program
{
    static void Main(string[] args)
    {
        Console.Write("Burchakni radianda kiriting: ");
        double a = double.Parse(Console.ReadLine());
        Console.WriteLine("Sinus: "+Math.Sin(a));
        Console.WriteLine("Kosinus: "+Math.Cos(a));

        Console.ReadKey();
    }
}
```

**Math.Cosh()** – burchakning giperbolik kosinusini hisoblaydi. Faqat *double* tipida ishlaydi.

**Math.E** – Math sinfining maydon (field)laridan biri. Fieldlar amal bajarish uchun emas, avvaldan belgilab qo'yilgan biror qiymatni qaytarish uchun ishlatiladi. Masalan, Math.E e sonining qiymatini *double* tipida qaytaradi. e=2,718281828459045.

**Math.Exp()** - o'zgarmas e sonini kiritilgan darajaga ko'taradi va hosil bo'lgan qiymatni qaytaradi. Kiruvchi va chiquvchi qiymatlar *double* tipida bo'ladi. Masalan, Math.Exp(1)=2,718281828459045; Math.Exp(2)=4,4816890703380645.

**Math.Floor()** - sonning butun qismi, kiritilgan sondan kichik yoki unga teng bo'lgan eng yaqin butun sonni qaytaradi. *double* yoki *decimal* tipida ma'lumot qabul qiladi va qaytaradi. Math.Floor(1.5)=1; Math.Floor(-1.5)=-2; Math.Floor(1.0)=1.

**Math.IEEERemainder()** - bir sonni boshqasiga bo'lgandagi qoldiqni hisoblaydi, faqat bu metodning ishlash algoritmi oddiy qoldiqnikidan boshqacharoq. a sonni b ga IEEERemainder orqali bo'lsak qoldiq `IEEERemainder(a,b) = a - (b * Math.Round(a / b))` umumiy formula bilan hisoblanadi. Ya'ni agar a/b ning kasr qismi 0.5 dan kichik bo'lsa IEEERemainder() ning qaytargan javobi oddiy qoldiq(a%b) bilan bir xil, aks holda a%b-b ga teng bo'ladi. Masalan, IEEERemainder(10,3)=-1; IEEERemainder(9,4)=1. Qiymat qabul qilish va qaytarish *double* tipida bo'ladi.

**Math.Log()** - sonning logarifmini hisoblaydi. *double* tipida ma'lumot qabul qiladi va qaytaradi. Ikki xil usulda ishlatish mumkin:

1. Agar bitta son kiritilsa shu sonning natural logarifmini hisoblaydi. Masalan, Math.Log(2,718281828459045) ifoda 1 ni qaytaradi.
2. Ikkita son Math.Log(a,b) ko'rinishida b asosga ko'ra a sonining logarifmini hisoblaydi. Math.Log(32,2) deb yozsak 2 asosga ko’ra 32 ning logarifmini hisoblab, bizga 5 ni qaytaradi.

**Math.Log10()** - sonning o’nli logarifmini hisoblaydi. Math.Log10(100) bizga 2 degan javobni qaytaradi. Qiymat qabul qilish va qaytarish *double* tipida bo'ladi.

**Math.Log2()** - sonning 2 asosga ko'ra logarifmini hisoblaydi. *double* tipida qiymat qabul qiladi va qaytaradi.

**Math.Max()** - ikki sondan kattasini aniqlab beradi. Kiruvchi parametr sifatida ixtiyoriy sonli tipdagi ikkita son kiritiladi, bizga ulardan kattasining qiymatini qaytaradi.

**Math.Min()** - ikki sondan kichigini topadi. Kiruvchi parametr sifatida ixtiyoriy sonli tipdagi ikkita son kiritiladi, bizga ulardan kichigining qiymatini qaytaradi.

**Math.PI** - bu Math sinfining yana bir maydon(field)i hisoblanadi. Pi sonining qiymati 3,14159265358979 ni *double* tipida qaytaradi.

**Math.Pow(a,b)** - a sonini b-darajaga ko’taradi. Kiruvchi parametrda ikkita son asos va daraja *double* tipida kiritiladi, bizga hisoblangan qiymatni qaytaradi. Masalan, Math.Pow(3,2) 9 ni qaytaradi.

**Math.Round()** - sonni yaxlitlaydi.

1. Agar kiruvchi parametrda bitta son Math.Round(a) ko’rinishida kiritilsa, a ni butun songacha yaxlitlangan qiymatini qaytaradi.
2. Agar ikkita son Math.Round(a,b) ko’rinishida kiritilsa, a sonni verguldan keyin b ta xonagacha yaxlitlangan qiymatini qaytaradi. Faqat haqiqiy (*double*,*decimal*) tipda qiymat qabul qiladi va qaytaradi.

**Math.ScaleB(x,n)** - `x*2^n` ifodaning qiymatini effektiv ravishda, yuqori tezlikda hisoblaydi. x soni *double* tipida, n soni *int* tipida bo'lishi kerak. Masalan, Math.ScaleB(3,4)=48.

**Math.Sign()** - sonning ishorasini aniqlab beradi. Agar son musbat bo’lsa 1 ni, manfiy bo’lsa -1 ni, nolga teng bo’lsa 0 ni qaytaradi. Kiruvchi parametr ixtiyoriy sonli tipda bo'lishi mumkin, lekin faqat int tipida qiymat qaytaradi.

**Math.Sin()** – burchakning sinusini hisoblaydi. Burchak qiymati radianda kiritiladi. Kiruvchi va qaytariluvchi parametrlar faqat *double* tipida bo'ladi. Math.Sin(3.141592653589793)=0;

**Math.Sqrt()** - sonning kvadrat ildizini hisoblaydi. Kiritiladigan va qaytaradigan son *double* tipida bo'ladi.

**Math.Tan()** - burchakning tangensini hisoblaydi. Burchak radianda kiritiladi. Kiruvchi va chiquvchi parametrlar faqat *double* tipida bo’ladi. Masalan, Math.Tan(3.141592653589793) ifoda 0 ni qaytaradi.

**Math.Tanh()** - burchakning giperbolik tangensini hisoblaydi.

**Math.Tau** - Math sinfiga tegishli uchinchi field, o'zgarmas **tau** sonining qiymati 6,283185307179586 ni qaytaradi.

**Math.Truncate()** - bu metod ham sonning butun qismini hisoblaydi. Haqiqiy (*double*, *decimal*) tiplarda ishlaydi. Musbat sonlarda Math.Floor() bilan bir xil ishlaydi. Lekin ularning farqi manfiy sonlarda namoyon bo’ladi. -3.14 ning butun qismini olib ko’radigan bo’lsak, Math.Truncate(-3.14) ifoda -3 ni, Math.Floor(-3.14) ifoda esa -4 ni qaytaradi. Matematik tomondan butun qism olish uchun Math.Floor() to’la mos keladi, lekin shuni unutmangki, Math.Truncate() ni ham o’z o’rni bor.

Keling, yuqoridagi metodlarni qanday ishlashini kodda yana bir bor ko'rish uchun biror ifodani kodda yozib ko'ramiz. Aytaylik, a soni kiritilganda quyidagi ifodaning qiymatini hisoblashimiz kerak:

![ifoda](https://user-images.githubusercontent.com/91861166/137533450-80fcc47b-d82b-4a02-b152-4cac8bab370a.jpg)

Yechim quyidagicha bo'ladi:

```csharp
using System;
namespace ifoda
{
  class Program
  {
    static void Main(string[] args)
    {
        Console.Write("a=");
        double a = double.Parse(Console.ReadLine());
        double b = Math.Pow(Math.Floor(Math.Acos(Math.Abs(a) / (Math.Abs(a) + 1))), Math.PI) +
          Math.Exp(Math.Sin(Math.Log(Math.Log(a), 2)));
        Console.Write("Javob: " + b);
        Console.ReadKey();
    }
  }
}
```


# For sikl operatori

Suxrob Xayitmurodov

Galdagi mavzuda sizlarni takrorlash operatorlari haqida tanishtirib o’taman va shu bilan birgalikda For Loop operatorini ham ishlash sintaksisini ya'ni qanday ishlashini ko’rsataman

Umuman olganda kod yozayotganingizda bir xil hisoblash jarayonini qayta qayta yozish qimmatli vaqtingizni o'g'irlab sizni bezor qilishi mumkin, masalan siz “Salom, Dunyo!” jumlasini 100 marta yozishingiz zarur bo’lib qoldi. Siz uni qayta qayta yozib chiqgan bo’larmidingiz, yo’q albatta. Bu dasturchining asabini buzib, ko'ziga baloday ko'rsatib qo'yishi aniq. Aynan ushbu muammoning oldini olish uchun takrorlash operatorlari ishlab chiqilgan, ya’ni siz ta’kidlab o’tilgan jumlani bir necha qator kod bilan nafaqat 100 marta balkim googel marta ham yozishingiz mumkin. Googel bu eng katta son bo’lib, siz unga 1 soni qo’shsangiz, aynan ushbu sonni googel o’zlashtiradi. Siz o’zingiz uchun ulardan o’zingizga qulay bo’lganini tanlab olishingiz mumkin.

Takrorlash operatorining C# da 4 xil turi mavjud:

•       For\
•       While\
•       Do-while\
•       foreach

foreach dan tashqari barcha operatorlar bir xil vazifani bajaradi, farqi ularning sintaksisida hisoblanadi, foreach ni ham albatta ko’rib o’tamiz

Keling endi For takrorlash operatori bilan tanishib chiqamiz:

For loop (operatorining) ishlash prinsipi quyidagicha

for (o’zgaruvchi ; munosabat amallari ; postfiks) { Operator yoki blok; (yoki sikl tanasi) }

Bu operator eng birinchi o’zgaruvchidan ishni boshlaydi, undan so’ng munosabat amallarini tekshiradi, har bir takrorlanish mobaynida u munosabat amallariga murojaat qiladi, agar munosabatlar to’g’ri bo’lsa operator yoki blokni bajaradi, postfiks esa undan so’ng bajariladi, agar noto’g’ri qiymatni olsa dasturimiz undan keyingi ya’ni operatorimizdan keyingi amallarni bajaradi yoki boshqa amallar yo’q bo’lsa, u to’xtaydi.

Masala: 1 dan 10 gacha bo’lgan sonlarni ko’rib chiqamiz:

```csharp
for(o’zgaruvchi ; munosabat amallari ; postfiks)
{
    Operator yoki blok; (yoki sikl tanasi)
}
```

Bu operator eng birinchi o’zgaruvchidan ishni boshlaydi, undan so’ng munosabat amallarini tekshiradi, har bir takrorlanish mobaynida u munosabat amallariga murojaat qiladi, agar munosabatlar to’g’ri bo’lsa operator yoki blokni bajaradi, postfiks esa undan so’ng bajariladi, agar noto’g’ri qiymatni olsa dasturimiz undan keyingi ya’ni operatorimizdan keyingi amallarni bajaradi yoki boshqa amallar yo’q bo’lsa, u to’xtaydi.

Masala: 1 dan 10 gacha bo’lgan sonlarni ko’rib chiqamiz:

```csharp
for(int i = 0; i <= 10; i++)
{
    Console.WriteLine(i + "\t");
}
```

Aynan ushbu 4 qator kod 100 marta yozishdan ko'ra yaxshiroq deb o'ylayman, sababini bilasiz!

Keling endi aynan ushbu kodni mulohaza qilamiz:

![](/files/-Mauf0Frk72lvsdjMwhm)

Bu yerda majburiy ajratuvchilar bo'lishi (nuqta, vergul mana men shu yerdaman deyishi)  shart, ularsiz biz for operatorida kod yoza olmaymiz (tan olavering bari bir yoza olmaysiz). Aynan ko’rsatilgan tartibda yozish ham shart emas. int i = 1 ni siklda tashqari holatlarda ham e’lon qilib sikl parametrini shunchaki i deb ham ketishimiz mumkin bo’ladi!

O'ylaymanki darsimiz qiziq bo'ldi va sizda hech qanday savol tug'ilmadi!!!


# While sikl operatori

Ilyosxo'ja Sulaymonov

Assalomu alaykum azizlar. Sizlar bilan takrorlash operatorlaridan (C# dasturlash tili deb yozib o’tirmayman) while va do-while bilan tanishamiz(tanishasiz ,mayli men ham qayta tanisharman, o’ylab ko’ray ok?). Xo’p bo’lmasa ketdik. while ham xuddi for singari takrorlash operatori. Buni bilganlar darmonda, bilmaganlar o’sha gap. Umumiy tuzilishi while(shart){operatorlar} while(shart) { Operatorlar; } bu while operatori zab ajoyibda. Ajoyibligi shuki har safar shartni tekshiradi. Agar true bo’lsa while ichidagi operatorlarni bajaradi. Agar false bo’lsa while ichida shuncha yozgan kodiyizni bir tiyinga olmaydida darrov keying amalga o’tadi. Masalan oddiy “salom” so’zini 10 marta yozmoqchimiz. Buning uchun quyidagicha kod kiritamiz

```csharp
int i = 1;
while(i<10)
{
  Console.WriteLine("salom");
  i = i + 1;
}
```

Ko’rib turganingizdek while ishimiz ancha osonlashadi. Bu while operatorini ifni akasi desak ham bo’ladi. Faqat else qismi yo’q xolos, ammo yaxshi tarafi sikl bajaradi. Endi siz bilan yana bir misol ko’ramiz.

```csharp
while(true)
{
    Console.WriteLine("salom");
}
```

Ana bu rosa zo’r bo’ldi. Endi bu sikl hech qachon tugamaydi. Ehh salomdan boshi chiqmay qoldi kimni bo’lsa ham

![Mana sizga!](/files/-MLTYCHZp-ykZ50t8PTc)


# Do-While sikl operatori

Ilyosxo'ja Sulaymonov

Assalomu alaykum hammaga derdimu ha mayli. Baribir assalomu alaykum. Xo’sh endi sizlr bilan do-while takrorlash operatori bilan tanishamizmi? Ha tanishamiz. Ketdik unda do-while xuddi for, while kabi takrorlash operatori bo’lib ulardan farqli ravishda avval amal bajarib so’ng shart tekshirarkan qoyilmisiz. Umumiy tuzilishi:\
*do {* \
&#x20;     *Operatorlar;* \
*}*\
while(shart); \
Demak do-while , while dan farqli ravishda avval amalni bajarib so’ng shartni tekshiradi. Agar shart true bo’lsa takrorlashni bajaradi, aks holda takrorlashni tugatadi. Dastur ishga tushirsangiz kamida bitta amal bajaradi. To’g’risi hamda o’lay deb shuncha kod yozasiz u ishlamasa alam qiladimi? do-while o’sha alam qilishni oldini oladida. Quyidagi misolni ko’rsak, 1 dan 10 gacha sonlar yig’indisi

```csharp
int i = 1, s = 0;
do
{
    s = s + i;
    i = i + 1;
} while (i <= 10);
```

{} figurali qavslar do-while siklida shart bo’lmasada, lekin ularni ishlatish dastur kodini o’qishni osonlashtiradi va while siklidan farqlashga yordam beradi Shunday qilib do-while operatori bilan ham tanishib olibmiz. Keling unda yana bir misol ko’ramiz. Nima demadingiz: Berilgan uch xonali sonni raqamlarini teskari tartibda yozib ekranga chiqarsin hozir nima deganimni tushunganlar tushundi, ya’ni 986 yozsak bizga 689 ni hosil qilsin kelishdikmi? Kelishmasak ham shuda endi ko’naverasiz.

```csharp
class sikl
{
    static void Main(string[] args)
    {
        int num;
        int nextdigit;
        Console.Write("Son: ");
        num = Convert.ToInt32(Console.ReadLine());
        Console.Write("Soning raqamlari teskari tartibda: ");
        do
        {
            nextdigit = num % 10;
            Console.Write(nextdigit);
            num = num / 10;
        }while (num > 0);
        Console.WriteLine();
        Console.ReadLine();
    }
}	
```

mana azizlar sizlarga aytmoqchi e yog’ee yozmoqchi bo’lgan(yozib bo’ldingku deydigan odam yo’g’aa) ma’lumotlar qisqacha shular. Boshlashda qanday gaz bosgan bo’lsangiz buyog’iga ham shunday davom eting.


# Foreach sikl operatori

Ilhomjon Bekmirzayev

Assalomu aleykum bo‘lajak dasturchilar hozir sizlar bilan **foreach** sikli bilan tanishib chiqamiz. **foreach** siklining **for**, **while**, **do while** sikllaridan asosiy farqi **foreach** sikliga shart berilmaydi. Foreach sikli asosan massivlar va kolleksiya qiymatlari bilan ishlashni osonlashtirish uchun mo‘ljallangan bo‘lib, bunda massivning har bir elementiga undagi elementlar sonini bilmagan holda barcha elementlariga murojaat qilish imkonini beradi.

**foreach** blok sxemasi quydagicha:

![](/files/-MaRqifoeNPzf5TrsddB)

```csharp
// Sintaksisi quyidagicha
foreach (var item in collection)
{
    // body
}

// O'zimizning tilda :)
foreach(<o`zgaruvchi turi> <o`zgaruvchi nomi> in <massiv nomi>)
{
    //Sikl tanasi
}
```

Bu yerda e’tibor qaratiladigan jihati o‘zgaruvchi turi massiv turi bilan mos kelishi lozim(olmaning tagiga olma tushadi deganlaridek…☺).

Ko'p gapirgandan ko'ra soddaroq misolda ko'rsak :)))

Biz avvaliga qiladigan ishimizni bilib olishimiz lozim, demak  biz qandaydir elementlarga ega massiv yaratamiz va foreach sikli orqali massiv elementlarini ekranga chiqaramiz.

```csharp
class Program
{
    static void Main(string[] args)
    {
        string[] mevalar = { "olma", "nok", "uzum", "shaftoli", "o`rik"};
        
        foreach (string meva in mevalar)
        {
            Console.WriteLine(meva);
        }
    }
}
```

Bu yerda biz **string** turidagi **mevalar** nomli massiv hosil qildik  va unga olma, nok, uzum, shaftoli, o\`rik qiymatlarini (massiv elementlarini) berib chiqdik.

Keyn esa foreach sikli string turidagi meva o’zgaruvchisiga mevalar massividagi elementlarini bitta-bitta olib uzatadi va har bir meva o’zgaruvchisini qiymatini ekranga chiqaramiz.


# Break

Sobirjonov O'tkirbek

Assalomu aleykum ! Har bir inson bir yoki bir nechta boks janglarini ko’rgan bo’lsa kerak albatta! Sizlar shu janglarda raund tugaganda bokschilarga “break”, “break” deb ularni to’xtatganiga guvoh bo’lgan bo’lsangiz kerak albatta. Hozir biz siz bilan manashu “break” lar haqida gaplashamiz

![Buni Tayson desak ham bo'larkan](/files/-MLTOvO7Gx6v26cr0i9Y)

Shu holatda anavi dabdalasi chiqqan bookschi shu so’zni intizorlik bilan kutadi. Va hakam “break” deb jangni to’xtatadi. Dasturlashda har bir kalit so’z amali bilan bog’liq demak bu yerda “break” so’zi jangni to’xtatsa dasturdagi “break” kalit so’zi siklni to’xtatadi.

Ko’p gap eshshakka yuk, Dasturda misol ko’rishga o’tsak.

```csharp
using System;
namespace boks
{
    class Program
    {
        static void Main(string[] args)
        {
            int hakamSana = 0;
            while (true)
            {
                hakamSana++;
                Console.WriteLine(hakamSana);
                if (hakamSana == 10) break;
            }
        }
    }
}
```

Jangda Hakam 10 gacha sanab Jangni tugatishi kerak edi to’g’rimi?! Bu dasturda ham huddi shunday boldi cheksiz ishlaydigan siklni biz “break” kalit so’zi bilan to’xtatdik. Natijada Qora oynaga 1..10 oralig’ida sonlar chiqarildi. “Break”ni vazifasini ozroq tushundingiz deb o’ylayman. Yana bir dasturni ko’rsak.

```csharp
using System;
namespace boks
{
    class Program
    {
        static void Main(string[] args)
        {
            int hakamSana = 0;
            while (true)
            {
                int secund = 0;
                while (true)
                {
                    secund++;
                    if(secund > 3 * 60)
                    {
                        Console.WriteLine("Raund Tugadi!");
                        break;
                    }
                }
            }
        }
    }
}
```

Ko’rsatilgan dasturda siz raund tugash dasturini ko’rdingiz

![Aloqasi yo;'q bo'lsa ham ko'rsataman)](/files/-MLTRHw1bsCMZrTuuMsR)

Boksning 1 raundi 3 minut bo’ladi va 3\*60 secund bo’ladi. Bu dasturda siz boks raund tugashini avtamatlashtira oldingiz. Va for siklida second 180 ga teng bo’lganida “break” bu dasturni siklni to’xtatadi. Siz “switch” case ni o’rganayotganingizda ham break kalit so’zini ishlatgansiz!

```csharp
using System;
namespace boks
{
    class Program
    {
        static void Main(string[] args)
        {
            string EngZorBokschi = "Bill Geyts";
            switch (EngZorBokschi)
            {
                case "Bill Geyts":Console.WriteLine("Bill Geyts Milliarder"); break;
                case "Ozodbek Nazarbekov": Console.WriteLine("U Qo'shiqchi"); break;
                case "Ferrari": Console.WriteLine("U mashina"); break;
                case "Mayk Tayson": Console.WriteLine("Endi U qaridi"); break;
                case "Shahram G'iyosov": Console.WriteLine("To'g'ri"); break;
                default: Console.WriteLine("....");
                    break;
            }
        }
    }
}
```

Bu dasturga e’tibor bering bu dastur natijada “Bill Geyts Milliarder” Degan yozuv chiqadi va break kalit so’zi casening amalini to’xtatadi


# Continue

Sobirjonov O'tkirbek

Keling bu darsda sizlar bilan “continue” kalit so’zi bilan tanishamiz. “continue” kalit so’zi Bu davom etish degan manoni bildiradi . Aslida “continue” kalit so’zidan juda ham kam Foydalanamiz. Chunki “continue” odatda sikllarning ichida keladi. Keling bir dastur ko’raylik

```csharp
using System;

namespace MyApplication
{
  class Program
  {
    static void Main(string[] args)
    {
      for (int i = 0; i < 10; i++) 
      {
        if (i %2 == 0) continue;
        else Console.WriteLine(i); 
      }    
    }
  }
}
```

Biz bu dasturda 1 dan 10 gacha bo’lgan toq sonlarni ekranga chiqarish dasturini tuzdik. Bu “continue” kalit so’zi siklni 1 qadam oldinga yur deb buyruq beradi va shu zahotiyoq Sikl (ya’ni bu rasmda for) qadami (ya’ni int i) ning qiymati 1 ga oshadi. “continue” buyrug’I juda ham oson bolgani uchun tushuntira oldim deb o’ylayman. Endi Dasturlarda ko’rsak!

```csharp
using System;

namespace MyApplication
{
  class Program
  {
    static void Main(string[] args)
    {
      for (int i = 0; i < 10; i++) 
      {
        if (i == 8) continue;
	      else Console.Write(i + “ “);
      }    
    }
  }
}
```

Natijada Consolega : 0 1 2 3 4 5 6 7 9 chiqariladi.


# Goto

Sobirjonov O'tkirbek

Siz tuynuklar haqida eshitganmisiz? Dasturlashda ham xuddi shunday tuynuklar bor. Bu tuynukardan qanday foydalanamiz deysizmi!?

Avval tuynukni qayerga olib borishi uchun uning chiqish joyini Aniqlab olishimiz kerak.

![Aniqlab olamiz va kerakli joydan turib shu yerga hech qanday shartsiz o’tish mumkin . Ya’ni avvalgi belgilagan tuynuk uchida chiqib kelinadi.](/files/-MM6hb-FmqbRPv8QCeqh)

![Demak tushuncha oldingizmi Dasturda shuni bir ko’rmaymizni nima dedingiz?](/files/-MM6hjL2_nRIbuZEQZlP)

## Demak boshladik. 1-misol

```csharp
using System;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            bool active = false;
            string say = "Salom";
            key:
            if (active)
            {
                Console.WriteLine(say);
            }
            if(active == false)
            {
                active = true;
                goto key;
            }
            Console.ReadKey();
        }
    }
}
```

Bu dasturda biz avval “key” nomli kalitni belgilab oldik.va kalit so’zdan keyin ‘:’ qo’yamiz. Dasturda shu qismga o’tib olishimiz uchun.&#x20;

Bu qismda dasturda active false qiymat olgan va 1- if shart bajarilmaydi.

Keyin 2-if shartini active qanoatlantirgani uchun  active  true qiymat oladi goto key buyrugi orqali key: deb boshlangan qismga o’tib ketadi. Va Consolega “Salom” deb chiqaradi. Va 2-if shartiga o’tadi bu qismda esa active true qiymatga ega bo’lgan edi. Va dastur bu safar 2-if shartini qanoatlantirmadi va dastur tugadi.

## 2-misol

```csharp
using System;
namespace GotoShartOperatori
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 0;
            if (n == 0) {
                while (true)
                {
                    if (n == 10)
                    {
                        goto key;
                    }
                    n += 2;
                }
            }
            Console.WriteLine("Asosiy");
            while (true)
            {
                Console.WriteLine("Salom");
            }
            key:
            Console.WriteLine("Qalaysiz!");
            Console.ReadKey();
        }
    }
}
```

\
Bu dasturda n==0 shart tekshiriladi va while sikliga tushib qoladi va n=10 bo’lganida bu sikladan chiqib ketadi va xatto undan keyin turgan

```csharp
while (true)
    {
        Console.WriteLine("Salom");
    }
```

Cheksiz Siklga tushib qolgan key: bilan boshlanuvchi qismga o’tib ketadi!

Demak tushunganday bo’ldingizmi . Ya’ni siz dasturda ixtiyoriy Qismga o’tish uchun avval bir kalit so’z belgilab olasiz. Va dasturda ixtiyoriy qismda “goto”

So’zidan keyin siz o’ziz belgilagan kalit so’zni yozib qoyasiz. Dastur sizni kodlaringizni o’qiyotganda. “Goto” kalit so’zni o’qiganda siz yozgan kalit qismga o’tib ketadi. Demak tushunarli “Avval qayerligini aniqlab olmiz va shu joyga kalit so’z yozib ketamiz, va dasturni ixtiyoriy joyidan shu yerga goto deb so’zidan keyin kalitni yozib o’tib olasiz”!!!


# Kommentlar

Suxrob Xayitmurodov

![](/files/-MLcnrZ4FA0ihEgumEa0)

Hech kod yozish mobaynida adashib ketgan paytlaringiz ham bo’lganmi. Menimcha bu hol bir necha bor takrorlangan. Shaxsan men har doim kodimni tartibga keltirmasam besh daqiqa ichida qaysi qatorga qanday kod yozganimni eslay olmayman, sababi kodim bir necha yuzlab qatorlarni o’z ichiga oladi. Shu sababli barcha qatorlarda ma’lum bir qismiga izohlar qoldirib ketaman. Izohlardan (kommentlardan) C# kodlarini tushuntirish, uni yanada tushunarli qilish, tartiblash va ixcham shaklga keltirish uchun foydalanish mumkin. Bu qanday bo’ladi? \
C# dasturlash tilida ikki xil kommentlar mavjud:\
1.Fikrlar uchun kommentlar, ya’ni siz yozgan kodingizni izohlab, uning qanday kodligini ta’kidlab o’tasiz, ushbu kommentni yozish uchun shunchaki ikkita **// beligisini yozasiz**

```csharp
//Konsolga chiqadigan satrli matn
Console.WriteLine("Shaxboz aka yengi epizodim deb doim videolarini boshlaydi");
```

2\. Ko’p qatorli kommentlar, ya’ni bir necha qator yozgan kodingizni izoh sifatida olib qo’yasiz, shunda kodingiz kompilyatsiya jarayonida e’tiborsiz qoldiriladi. Uni /\**mana shular orasiga yozasiz\**/ :

```csharp
/*
string fo0 = COnsole.ReadLine();
string[] tokens = foo.Split(',');
List<int> nums = new List<int>();
int oneNum;
foreach(string s in tokens) {
    if(Int32.TryParse(s, out oneNum))
        num.Add(oneNum);
}
*/
```

Alohida aytib o’tish kerak! Kommentga olingan har qanday kod yoki ta’kid C# tomonidan e’tiborga olinmaydi.


# Essential (muhim)


# Funksiya

Xolbek Xoliyorov

C# dasturlash tilida funksiyalar nimaligini o’rganishdan oldin funksiyaning o’zi nima u bizga nega kerak degan savollarga javob topamiz.

**Funksiya nega kerak ?**\
Biz biroz yirikroq dastur yozish mobaynida juda ko’p bir xil bo’lgan vazifani qayta va qayta yozayotgandek bo’lamiz. Bu xuddi kuni bilan paxta terayotgan kishining ishiga o’xshaydi qaniydi bitta robot bo’lsayu unga bir marta paxta terishni o’rgatib qo’ysak keyin har safar aytganingda paxtani terib qo’ysa deb orzu qiladi paxta teruvchi , albatta terimchining bu orzusini amalga oshirish qiyin . Lekin sizning ishingizni (ya’ni kodlashda bir vazifani qayta yozishni) yengillashtirishning yo’li bor , bu yerda bizga Funksiyalar yordamga keladi

**Funksiya nima?**\
Bir marta kod yozib uni dasturning istalgan joyida istalgancha ishlatish imkonini beruvchi operatorlar guruhi Funksiya deyiladi. Bu huddi yuqoridagi misolimizga o’xshash bir marta qanday qilishni o’rgat va xoxlagan vaqting xoxlagan joyingda ishlat. Funksiya dasturchining kodini sezilarni darajada qisqartiradi va bu orqali dastur kodini o’qish osonlashadi va qotira hajmidan ham yutiladi.

**C# da funksiyadan foydalanish**\
Dasturlashda funksiyalar ikki toifaga bo’linadi\
• Qiymat qaytaruvchi\
• Qiymat qaytarmaydigan

Dastlab biz **qiymat qaytaruvchi funksiyalar** ni ko’rib chiqamiz. Qiymat qaytaruvchi funksiyalar malum bir qiymatni (int ,float ,string va boshq) qaytaradi Qiymat qaytaruvchi funksiya larning tuzilishini ko’ramiz

![](/files/-MLbGoWIihArDZuf-g7h)

Bularning barchasiga alohida to’xtalib o’tamiz\
1\. - bu funksiya qaytaradigan qiymat bo’lib turli xil ma’lumot turlaridan foydalanishimiz mumkin masalan int, float string kabilar.\
2\. - funksiyaning nomi yani uni chaqiradigan ism deyishimiz ham mumkin unga ism tanlayotganda lotin alifbosidagi katta va kichik harflar , raqamlar va tagchiziq (‘\_’) foydalangan holda , raqamdan boshlamasdan va c# tilidagi kalit so’zlardan foydalanmagan holda xoxlagan ismni berishimiz mumkin.\
3\. (\<parametrlar>) – bu funksiya yakuniy qiymatni yaratish uchun foydalanadigan yordamchilar deyishimiz mumkin ushbu yordamchilar sifatida esa turli xil malumot tipidagi o’zgaruvchilar keladi . yordamchilar sifatida 0 tadan xoxlagancha o’zgaruvchilar bo’lishi mumkin ular quyidagicha yoziladi (int a, float b, int c) . 4. // funksiya tanasi - ushbu qism funksiyaning asosiy qismi hisoblaning qaytariladigan yakuniy qiymatgacha bo’lgan barcha ishlar shu yerda qilinadi va figurali qavs (‘{‘) bilan boshlanadi ushbu qismda parametr sifatida kiritilgan o’zgaruvchilar ham ishlatiladi.\
5\. // return - ushbu amal biz funksiyaning qaytaradigan qiymatini aniqlaydi. ning turi funksiyada elon qilingan dastlabki qiymat bilan bir xil bo’lishi shart.yani funksiya int turida bo’lsa biz return dan keyin ham int turidagi o’zgaruvchi bo’ladi.\
Ming marta eshitgandan ko’ra bir marta ko’rgan yaxshi deganlaridek biz C# tilida Funksiya ga oddiygana ikki sonda kattasini topuvchi funksiya orqali misol keltiramiz

```csharp
int max( int a , int b)
{
    int max;
    if(a>b) max = a;
    else max = b;
    return max;
}
```

**C# Console dasturida funksiyadan foydalanish**

```csharp
using System;
namespace function_test
{
    class Program
    {

        static void Main(string[] args)
        {
            int a = 5, b = 8;
            Console.WriteLine(max(a, b));
            Console.ReadKey();
        }
        static  int max(int a, int b)
        {
            int max;
            if (a > b)
                max = a;
            else
                max = b;
            return max;
        }        
    }
}
```

output: 8

Yuqorida console dasturida max yani ikki sondan kattasini topuvchi funksiya yaratildi va undan dasturning Main qismida foydalanildi. Albatta bu yerda funksiyaning foydasi yaqqol sezilmagandir ammo siz dastur ichida funksiyani bir necha marotaba foydalansangiz naqadar foydali ekanligini tushunasiz.

**Qiymat qaytarmaydigan funksiyalar**\
Agar biz funksiyalarni xizmatchi inson deb bilsak qiymat qaytaradigan va qaytarmaydigan funksiyalarni shunday tariflashimiz mumkin . Deylik xizmatchiga qanchadir pul(ya’ni parametr) berib do’konga jo’natamiz va bizga aytgan narsamizni (qaytaradigan qiymat) ni olib keladi bu qiymat qaytaradigan funksiyaga misol bo’ladi . boshqa xizmatchiga esa pul(ya’ni parametr) berib unga hovlidagi qandaydir ishlarni aytamiz va u aytgan ishlaringizni qildi lekin sizga hech narsa qaytarib kelmadi bu qiymat qaytarmaydigan funksiyaga misol bo’la oladi. Qisqa qilib aytganda qiymat qaytarmaydigan funksiyaning qaytaruvchi qiymati bo’lmaydi va u qandaydir vazifani bajargan bo’ladi.

Endi esa qiymat qaytarmaydigan funksiyalarning tuzilishini ko’rib chiqamiz

![](/files/-MLbI3sY2TsbkEFA4knn)

Qiymat qaytarmaydigan funksiyaning qiymat qaytaradigan funksiyadan asosiy farqi bu funksiyalar qaytariladigan qiymat turi o’rniga ‘void’ kalit so’zi bilan boshlanadi va qaytariladigan qiymat return yozilmaydi. Endi esa qiymat qaytarmaydigan funksiyaga misol yozamiz

```csharp
void print(string s,int n)
{
    for(int i=0;i<n;i++)
            Console.WriteLine(s);
}
```

Bu shunchaki s matnni n marta takma tak chiqaruvchi funksiya Bundan foydalanishni yana console dasturda ham ko’ramiz.

```csharp
using System;
namespace function1
{
    class Program
    {

        static void Main(string[] args)
        {
            string text = "dot-net.uz";
              int n = 3;
            print(text, n);
        }

        static void print(string s, int n)
        {
            for(int i = 0; i < n; i++)
              Console.Write(s + " ");
        }

    }
}
```

Output: dot-net.uz dot-net.uz dot-net.uz

Xulosa qilib aytadigan bo’lsak funksilar bizning og’irimizni yengil uzog’imizni yaqin qiluvchi yordamchi zamonaviy dasturlash tillarini funksiyalarsiz tasavvur qilib bo’lmaydi . Katta loyiha qila turib funksiyalardan foydalanmaslikni yangi uyni faqat qo’l mehnati bilan qurmoqchi bo’lgan inson harakati bilan o’xshatish mumkin. Bu boshlanishi edi keyingi darslarda funksiyalarga yanada kengroq to’xtalamiz.


# Funksiyani qiymat orqali chaqirish

Xolbek Xoliyorov

Funksiya larni qiymat orqali chaqirish nima biz bu tushunchani tushunish uchun hayotiy misol ko’rib o’tamiz. Tasavvur qilamiz biz muzqaymoq sotishni rejalashtirmoqdamiz. Biz shokoladli, mevali va qaymoqli muzqaymoq yaratmoqchimiz ,endi qilamiz har biri uchun alohida qurilma sotib olamizmi yoki ichiga soladigan maxsulotga qarab har xil musqaymoq chiqadigan bitta qurilma sotib olamizmi, albatta sizga ham ikkinchi variant maqul chunki bu biz uchun juda qulay va ortiqcha harajatdan ozod qiladi.

**Nega kerak?**

Endi funksiyaga qaytsak funksiyada ham deyarli shunday vaziyat. Ba’zan biz bitta funksiya orqali har xil qiymat olishga ehtiyoj sezamiz. Masalan ikki sondan kattasini topadigan funksiya yaratdik deylik uni biz int turidagi qiymat qaytaradigan qilib yaratdik , va float parametr kiritib ishlatganimizda bizga bu xatolik olib keldi nima endi float uchun alohida funksiya yozishimiz kerakmi , yo’q albatta funksiyani qiymatini chaqirish orqali bu muammoni yechamiz.

**Yaratish**

Demak bu yerda bir xil nomga ega va bir biridan parametr orqali (ya'ni parametrlar soni yoki parametr turi) farq qiluvchi funksiyalar yoziladi.

```csharp
int max(int a, int b)
{
    int max;
    if (a > b)
        max = a;
    else
        max = b;
    return max;
}
```

```csharp
float max(float a, float b)
{
    float max;
    if (a > b)
       max = a;
    else
       max = b;
    return max;
}
```

Ko’rib turganingizdek biz max funksiyasini chaqirsak qaysi ishlaydi degan savol tug’iladi albatta. Bu yerda kiritilgan parametr orqali funksiya chaqiriladi.

Misol uchun:

max(1.5 , 9.6) ko’rinishida funksiyani chaqirsak demak 2-funksiya chaqiriladi. max(5 , 9)  ko’rinishda chaqirganimizda esa 1-funksiya chaqiriladi.

**Dasturda Foydalanish**

Endi esa ushbu misolni Console oynada ko'rib chiqamiz:

```csharp
using System;
namespace function2
{
    class Program
    {  
        static void Main(string[] args)
        {
            Console.WriteLine(max(11, 5));
            Console.WriteLine(max(1.4f, 5.4f));

            Console.ReadKey();
        }
        static int max(int a, int b)
        {
            int max;
            if (a > b)
                max = a;
            else
                max = b;
            return max;
        }
        static float max(float a, float b)
        {
            float max;
            if (a > b)
                max = a;
            else
                max = b;
            return max;
        } 
    }
}

```

* << output&#x20;
* 11
* 5.4

Xulosa qilib aytganda funksiyalarni qiymati orqali chaqirish imkoniyati bizga bitta ovqatning turli xil variantini taklif etatayotgan oshpazga o'xshaydi, hamma o'ziga ma'qulini tanlashi mumkin!


# Funksiyada Ref kalit so'zidan foydalanish

Xolbek Xoliyorov

Biz shu vaqtgacha foydalangan funksiyalarda parametr sifatida berilgan o’zgaruvchilardan ma’lum natija olish uchun foydalandik, lekin biz hali parametrning qiymatini o’zgartirib ko’rmabmiz. Xo’sh parametrning qiymatini o’zgartirib nima qilamiz degan savol tug’ilishi tabiiy. Keling ikki sonni qiymatlarini o’zaro almashtiruvchi ‘swapp’ atalmish funksiya yaratib ko’ramiz.

Bu funksiyani ikki idish usuli (ya’ni ikkita idishdagi mahsulotlarni o’zaro almashtirish uchun uchinchi idishdan foydalanish ) yordamida tayyorlaymiz.

```csharp
void swapp(int a, int b)
{
    int k = a;
    a = b;
    b = k;
}
```

Va buni dasturda ishlatamiz:

```csharp
using System;
namespace function3
{
    class Program
    {  
        static void Main(string[] args)
        {
            int a = 8, b = 5;
            swapp(a, b);

            Console.WriteLine(a+"  "+b);
            Console.ReadKey();
        }
        static void swapp(int a, int b)
        {
            int k = a;
            a = b;
            b = k;
        }
    }
}
```

<\<output: 8    5

\
Afsuski natija biz kutgandek chiqmadi, ikki son o’z o’rnida chunki funksiya parametrlari standart holatda funksiya ichida o’zgarishlari funksiya tashqariga ta’sir qilmaydi. Bu muammoni hal qilish uchun bizga **ref** kalit so’zi yordamga keladi.

Biz yana yuqoridagi algoritm orqali funksiya yaratib olamiz faqat endigi safar ref yordamida.

```csharp
static void swapp(ref int a, ref int b)
{
    int k = a;
    a = b;
    b = k;
}
```

Va yangi funksyiani chaqirishda ham ref dan foydalanamiz.

```csharp
using System;
namespace function3
{
    class Program
    {  
        static void Main(string[] args)
        {
            int a = 8, b = 5;

            swapp(ref a,ref b);

            Console.WriteLine(a+"  "+b);
            Console.ReadKey();
        }
        static void swapp(ref int a,ref int b)
        {
            int k = a;
            a = b;
            b = k;
        }
    }
}
```

<\<output : 5    8

Va nihoyat biz kutgan natija ikki sonning o'rni almashmoqda buni **ref** kalit so'zisiz yaratish juda qiyin bo'lardi.

### Xulosa

**ref** kalit so’zi qachonki biz funksiya parametri faqat kerakli natija uchun vosita sifatida emas balki parametrni o’zining qiymatini o’zgartirish ustuvor vazifa bo’lsa biz uchun juda zarur bo’ladi.


# Funksiyada Out parametri

Xolbek Xoliyorov

Biz shu vaqtgacha funksiya bilan ishlash davomida bir nechta parametrlar orqali biror qiymatni topish va undan foydalanishni ko’rdik. Lekin biz bitta funksiya bir emas, bir nechta qiymatni aniqlashi kerak bo’lib qolsa nima qilamiz? Misol uchun kvadratning tomoni yordamida uning yuzasini, peremetrini va ichki chizilgan aylana radiusini hisoblaydigan funksiya yaratishimiz kerak. Buni odatiy holda har biri uchun alohida funksiya yozib chiqishimiz kerak. Lekin **out** yordamida buning hammasi oson bo'lib qoladi!!!

### E'lon qilish

Ming marta maqolani o'qigandan ko'ra bir marta dastur kodini ko'rgan yaxshi!:)))

```csharp
void kvadrat(float a,out float  yuza, out float peremetr, out float radius)
{
    yuza = a * a;
    peremetr = 4 * a;
    radius = a / 2;
}
```

Demak out parametrli o’zgaruvchi oldidan ‘out’ kalit so’zi ishlatiladi.

Yuqoridagi misolda funksiyani chaqirgandan keyin yuza , peremetr va radiusning qiymatidan foydanishimiz mumkin va ular oldindan qiymatga ega bo’lishi shart emas!

### Foydalanish

Endi esa konsol oynada ushbu funksiyani chaqirib ko'ramiz.

```csharp
using System;
namespace function4
{
    class Program
    {  
       static void Main(string[] args)
        {
            float a = 5;
            kvadrad(a, out float yuza1, out float peremetr1, out float radius1);

            Console.WriteLine(yuza1+"  "+peremetr1+" "+radius1);
            Console.ReadKey();
        }
        static void kvadrad(float a,out float  yuza, out float peremetr, out float radius)
        {
            yuza = a * a;
            peremetr = 4 * a;
            radius = a / 2;
        }
    }
}
```

<\<output 25    20    2.5

* Ko'rib turganingizdek out parametrlar qiymatga ega emas
* Qiymatga ega bo'lgan o'zgaruvchilarni ham **out** bilan chaqirishimiz mumkin
* **out** parametrli o'zgaruvchi funksiya tashqarisida e'lon qilinmagan, lekin tashqarida foydalanish mumkin
* **out** parametr sifatida oldin funksiya tashqarisida e'lon qilingan o'zgaruvchilardan foydalanishimiz mumkin.

{% hint style="info" %}
Eslatma:

**Funksiyada out parametrli o'zgaruvchi e'lon qilib foydalanmaslik xatolikka olib keladi.**
{% endhint %}

### Xulosa

Funksiyaning out parametri orqali e'lon qilingan o’zgaruvchini funksiya ichida o’zgartirishimiz mumkin va funksiya tashqarisida ham bu o’zgarish saqlanib qoladi. Funksiyada odatiy e'lon qilingan o’zgaruvchilarda esa bu hodisa ro’y bermaydi.

Va shuningdek bu imkoniyatlar **ref** kalit so’zida ham mavjud, lekin unda o’zgaruvchining dastlabki qiymati aniq berilishi shart.

*E'tiboringiz uchun raxmat!!!*


# Massiv

Shohruh Nosirov

C#  dasturlash tilida kompyuter xotirasiga bir o’zgaruvchi yordamida bir nechta qiymatlarda foydalanishga to’g’ri keladi. Bir o’zgaruvchi bilan bir nechta qiymat ustida amallar bajarish uchun berilgan ma’lumotlar bir turga mansub bo’lishi kerak. C#  dasturlash tilida bir o’zgaruvchi yordamida bir nechta qiymatlardan foydalanish uchun massiv degan turdan foydalaniladi. Dasturlash tillarida ro’yxat yoki jadval ko’rinishidagi ma’lumotlarni massiv deb atashadi. Massiv so’zining ma’nosi o’lcham, o’lchov demakdir. Massivning barcha elementlari bitta turga mansub bo’lib, ular bitta nom bilan nomlanadi va bir-birlaridan nomerlari (indekslari) bilan farq qiladi.

Endi dasturdagi ma’lumot strukturalari bilan tanishishni boshlaymiz. Dasturda ikki asosiy tur ma’lumot strukturalari mavjuddir. Birinchisi statik, ikkinchisi dinamikdir. Statik deganimizda xotirada egallagan joyi o’zgarmas, dastur boshida beriladigan strukturalarni nazarda tutamiz. Statik massivlar elementlar soni oldindan ma’lum bo’lgan va initsializatsiyalangan (qiymat belgilangan) massivlar hisoblanadi.  Dinamik ma’lumot tiplari dastur davomida o’z hajmini, egallagan xotirasini o’zgartirishi mumkin. Dinamik massivlar esa elementlari soni oldindan ma’lum bo’lishi va uni initsializatsiyalash (qiymat belgilash) shart emas. Statik massivlarning kamchiliki shundaki, agar ularning o’lchamini oldindan juda katta olinsa-yu, uning ko’p qismi keraksiz qolib ketsa, u holda xotira behuda sarflanishiga olib keladi. Shu muammoni hal qilish maqsadida massivlar C# tilida asosan dinamik tarzda e’lon qilinadi. Massivlar dasturlashda eng ko’p qo’laniladigan ma’lumot tiplaridir. Massivlar hotirada ketma-ket joylashgan, bir tipdagi o’zgaruvchilar guruhidir. Alohida bir o’zgaruvchini ko’rsatish uchun massiv nomi va kerakli o’zgaruvchi indeksini yoziladi.

{% hint style="info" %}
***Ta’rif:** Bir turga mansub bo’lgan yagona nom bilan saqlanuvchi tartiblangan ma’lumotlar majmuasi massiv deyiladi.*
{% endhint %}

Massivlar yagona o’zgaruvchi bilan kompyuter xotirasiga saqlanadi, uning elementlari ma’lum bir indekslar bilan tartiblab joylashtiriladi. Massivlar yagona nom bilan bir nechta qiymatni o’zida mujassamlashtiradi, bularga matematikadagi vektorlarni misol keltirish mumkin. Vektor ham yagona nom bilan saqlanib uning tarkibida bir nechta qiymatni o’zida mujassamlashadi. Vektorning ham elementlari bir turga mansub va tartiblangan bo’ladi.

### **Bir o’lchovli massivlar**&#x20;

Odatda massivlar zarurat, katta hajmdagi tartiblangan, lekin chekli elementlarga oid masalalarni hal etishda yuzaga keladi. Dastur ishlatilishi davomida massivlar aniq nomga ega bo’lishi va uning elementlari ma’lum bir turda bo’lishi kerak. Bir o’lchovli massivlar kompyuter xotirasiga quyidagi shaklda saqlanadi

![](/files/-MZzs1i2FOu4hoG8NeGw)

Massiv tarkibida **elementlar** mavjud bo’ladi. Massivning eng ko’pi bilan ketishi mumkin bo’lgan elementlar soni uning **o’lchamini** bildiradi. Massivning elementi turgan o’rni uning **indeksi** deyiladi. Massivning elementiga uning indeksi orqali murojaat qilinadi. Massivning indeksi sifatida butun sonlar xizmat qiladi. Har bir massiv o’zining individual nomiga ega bo’lishi kerak, ya’ni bir xil nomdagi massivlar bo’lmaydi. Ularning nomi oldin e’lon qilingan oddiy o’zgaruvchi nomi bilan ustma-ust tushmasligi kerak.

&#x20;**Statik** massivlarni e’lon qilishning umumiy ko’rinishi quyidagicha:

{% hint style="info" %}

***\<tip> \[]\<massiv\_nomi>={boshlang’ich qiymatlar}***
{% endhint %}

Bunda *{boshlang’ich qiymatlar}* albatta bo’lishi kerak. Misollar:

```csharp
int []A={1,4,3,1};
string[] B = { “olma”, “gilos”, “anor”};
double[] C = { 0.005, 1.234, 12.5, 13.5, 10.6 };
```

\
Yuqoridagi massivlarda massivning o’lchami uning initsializatsiya qismida qatnashgan elementlar soni bilan aniqlanadi. C# tilida xuddi C++ da bo’lgani kabi element indeksi 0 dan boshlanadi. A\[0] indeksli element 1 ga teng, B\[1] indeksli element esa “gilos” ga teng va h.

Aytib o’tganimizdek, C# tilida massivlar xotiradan unumli foydalanish maqsadida massivlarni dinamik tarzda e’lon qilishga kelishib olingan. Dinamik tarzda massivni e’lon qilishning umumiy ko’rinishi quyidagicha:

{% hint style="info" %}
***\<tip> \[] \<massiv\_nomi>=new \<tip>\[o’lcham]***
{% endhint %}

Bu yerda **new** operatori \<o’lcham>ga mos ravishda xotiradan joy ajratadi. Dinamik massivlarni e’lon qilishga doir misollar:

```csharp
n = Convert.ToInt32(Console.ReadLine());
int[] M1 = new int[10];
float[] M2 = new float[100];
double[] M3 = new double[n];
```

\
M1 va M2 nomli massivlarning elementlari uchun 10 va 100 ta joy ajratilgan. Ular ham dinamik massiv hisoblanadi. M3 massiv uchun xotiradan qancha joy ajratish foydalanuvchining o’ziga havola qilingan, ya’ni n o’zgaruvchisi klaviaturadan kiritiladi, bu o’zgaruvchi qiymati esa M3 massiv o’lchami sifatida qabul qilinadi. M3 massiv dinamik massivga yorqin misoldir.

Dinamik massiv o’lchami ham statik massiv kabi aniqlanishi lozim, faqat bunda u dastur ishlashi davomida anqlanishi bilan static massivdan farq qiladi.

Indekslar massiv elementlariga murojat qilish uchun ishlatiladi. Indeks massivdagi element sonini bildiradi .Massivdagi to’rtinchi elementga murojat qilish uchun biz 3 indeksidan foydalanishimiz kerak. Misol uchun :num\[3]. Massiv elementlarining qiymatlarini olish va o’rnatish uchun indekslardan foydalanamiz.

```csharp
int[] nums=new int [4];
nums[0]=1; 
nums[1]=2;
nums[2]=3;
nums[3]=5;
Console.ReadLine(nums[3]);   //5
```

Va bizda faqat 4 ta element uchun belgilangan massiv mavjud bo’lgani uchun , masalan oltinchi elementni qo’llay olmaymiz nums\[5]=5;.  Agar biz buni qilishga harakat qilsak biz **IndexOutOfRangeException**-ni  olamiz.

Statik massivlar elementlar oldindan aniqlanadi. Buning uchun sikl operatorlariga murojaat qilamiz. Masalan, quyidagi misolda dinamik massivga qiymat berish hamda uning elementlarini chop etish amallar ko’rsatilgan. Biz massiv elementlari bilan ishlashimiz uchun for sikl operatori kerak buladi. Bu haqida yetarlicha bilimga ega bo’lmasayiz [quyidagi link](https://dot-net.uz/basic/starter/for-sikl-operatori) orqali o’tsangiz Starter bulimida Suxrob Xayitmurodov yetarlicha malumot bergan. Agar for sikl operatori haqida malumotga ega bulsayiz davom etamiz.

```csharp
using System;
internal class ArrayExample
{
    private static void Main()
    {
        int[] A = new int[10];
        int i;
        for (i = 0; i < 10; i = i + 1)
            A[i] = i;
        for (i = 0; i < 10; i = i + 1)
            Console.WriteLine(‘A[‘ + i + ’]: ’ + A[i]);
    }
}
```

Bu dasturda A massivning elementlari sifatida i ning qiymatlari kelmoqda. Xuddi shunday massiv elementlarini klaviatura orqali ham kiritish mumkin. Buning uchun quyidagi kodni ko’raylik:

```csharp
using System;
 
internal class ArrayExample
{
    private static void Main()
    {
        int[] A = new int[10];
        int i;
        for (i = 0; i < 10; i = i + 1)
            A[i] = Convert.ToInt32(Console.ReadLine());
        for (i = 0; i < 10; i = i + 1)
            Console.WriteLine(‘A[‘ + i + ’]: ’ + A[i]);
    }
}
```

Massiv elementlari qiymatlaridan foydalanishga doir quyidagi sodda misolni ko’rib chiqaylik.

> \\
>
> **Men Shahbozga  judayam qiziqarli matematik masala berdim. Masala sharti quyidagicha: Men unga 10 ta son aytaman ularning yig’indisini topib 10 ga bo’lishi kerak buladi. Keyin Shahboz menga shu kodni yozib berdi.** **Sizham bu kodni o’z kompyuteringizda tekshirib kuring.**

```csharp
using System;
 
internal class Average
{
private static void Main()
    {
        int[] A = new int[10];
        int i;
        double S = 0;
        Console.WriteLine("Sonlarni kiriting");
        for (i = 0; i < 10; i = i + 1)
            A[i] = Convert.ToInt32(Console.ReadLine());
        for (i = 0; i < 10; i++)
            S += A[i];
        S = S / 10;
        Console.WriteLine(S);
    }
}
```

Massivlar bilan ishlaganda uning o’lchami chegarasidan chiqib ketmaslik lozim. Agar bu holat yuz bersa C# kompilyatori **IndexOutOfRangeException** xatoligi haqida xabar beradi. Bu xatolikni siz ham sinab kurmoqchi bulsangiz quyidagi kodni kiritib , ishlatib kuring:

```csharp
using System;
 
internal class ArrayErr
{
    private static void Main()
    {
        int[] sample = new int[10];
        int i;
        // Chegaradan chiqish holati yuz bermoqda 
        for (i = 0; i < 100; i = i + 1)
            sample[i] = i;
    }
}
```

Massivlar haqida boshlang’ich malumotlarga ega bo’ldingiz degan umiddaman.


# Funksiyalarda massivdan foydalanish

Faxriddin Xushnazarov

Hozir biz siz bilan funksiyalarda massivlardan foydalanishning bir nechta hollarini ko’rib chiqamiz.

1. Keling Python dasturlash tilidagi *range()* funksiyasiga o’xshash funksiyani biz C# dasturash tilida tuzib ko’ramiz. Izoh: *range()* – asosan ikkita argument qabul qiladi aytaylik n va m, ushbu funksiyaning vazifasi n dan m gacha bo’lgan butun sonli array ni qaytaradi(m kirmaydi).

```csharp
  static int[] Range(int n, int m) 
    { 
        int[] range = new int[m - n]; 
        int k = 0; 
        for(int i=n; i<m; i++) 
            range[k++] = i; 
        return range; 
    } 
```

Bu yerda biz *Range* funksiyasining type sifatida *int\[]* massiv typeni berdik. Endi ushbu funksiyadan foydalanib n dan m gacha bo’lgan butun sonlar yig’indisini hisoblaymiz:

```csharp
using C=System.Console; 
using System.Linq; 
public class Program 
{ 
    public static int[] Range(int n, int m) 
    { 
        int[] range = new int[m - n]; 
        int k = 0; 
        for(int i=n; i<m; i++) 
            range[k++] = i; 
        return range; 
    } 
    public static void Main(string[] args) 
    { 
        int n,m; 
        C.Write("n="); 
        n = int.Parse(C.ReadLine()); 
        C.Write("m="); 
        m = int.Parse(C.ReadLine()); 
        C.WriteLine($"{n} dan {m} gacha bo'lgan yig'indi={Range(n,m+1).Sum()}"); 
    } 
} 
```

1. Endi funksiyaning argumentlariga massivlardan foydalanishni ko’rsak.\
   Funksiyaning argumentiga massiv ham xuddi o’zgaruvchidek ishlatiladi Misol uchun: `<type> funksiyaNomi(int[] x, string[] y){}`

Keling biz **System** nomlar fazosidagi **Array** classining **Sort()** metodiga o’xshash funksiya yaratib ko’ramiz. Izoh: **Array.Sort** metodinig argumentiga massivni bersak ushbu metod bizga bergan massiv elementlarini o’sish tartibida tartiblaydi. Biz faqat *int* typedagi massivni sort qiladigan funksiya yozamiz!

```csharp
static void Sort(ref int[] massiv) 
  { 
      int x; 
      for(int i=0; i<massiv.Length-1; i++) 
          for(int j=i+1; j<massiv.Length; j++) 
          { 
              if (massiv[j] < massiv[i]) 
              { 
                  x = massiv[i]; 
                  massiv[i] = massiv[j]; 
                  massiv[j] = x; 
              } 
          } 
  } 
```

Xop bu funksiyani endi ishlatib ko’ramiz:

```csharp
   static void Main(string[] args) 
   { 
       int[] mas = { 5, 4, 2, 1, 7, 45, 41, 6, 3, 4 }; 
       Sort(ref mas); 
       foreach (int x in mas) 
           Console.Write(x+", "); 
   } 
```

Natija: `1, 2, 3, 4, 4, 5, 6, 7, 41, 45,`

Endi biz ushbu funksiya yordamida massivdagi eng katta va eng kichik elementni ham topishimiz mumkin:

```csharp
static void Main(string[] args) 
{ 
 int[] mas = { 5, 4, 2, 1, 7, 45, 41, 6, 3, 4 }; 
 Sort(ref mas); 
 Console.WriteLine($"eng kichigi: {mas[0]}, eng kattasi: {mas[mas.Length - 1]}"); 
} 
```

Natija: `eng kichigi: 1, eng kattasi: 45`

Demak biz funksiyalarning type va ularning argumentlarida bemalol massiv typelaridan foydalana olar ekanmiz.


# Ko'p o'lchamli massiv

Mirzayev Bahodirjon

Massivlar **daraja** yoki **o'lchovlar soni** kabi tushuncha bilan tavsiflanadi. Massivlar 1, 2, 3 yoki n o’lchamli bo’lishi mumkin. Ko’p o’lchmali massivlarni 2 o’lchamli massivlar misolida ko’rib boramiz Bir o’lchovli massivlarni bitta gorizontal qator kabi tasavvur qilishimiz mumkin, misol uchun:

```csharp
int[] nums1 = new int[] { 0, 1, 2, 3, 4};
```

Vizual ko’rinishda bu massiv:

![image](https://user-images.githubusercontent.com/81855769/123962446-e98ec080-d9ca-11eb-9420-48b1fba3373f.png)

Endi esa 2 o’lchamli massivga misol ko’ramiz:

```csharp
int[,] nums2 = { { 0, 1, 2 }, { 3, 4, 5 } };
```

Vizual ko’rinishda bu massiv:

![image](https://user-images.githubusercontent.com/81855769/123962584-0d520680-d9cb-11eb-9c42-00e565b36a2b.png)

Ko’p o’lchamli massivlarni e’lon qilish uchun kvadrat qavs ichiga vergul qo’yiladi, yani \[,] ikki o’lchamli massiv, \[,,] uch o’lchamli massiv va hokazo.

```csharp
int[,] arr2d; // ikki o’lchamli massiv
int[,,] arr3d; // uch o’lchamli massiv
int[,,,] arr4d; // to’rt o’lchamli massiv
int[,,,,] arr5d; // besh o’lchamli massiv
```

C# 32 o’lchovgacha bo’lgan massivlarni qo’llab quvvatlaydi.

**32 o’lchovgacha Karl, 32!**

Odatda 1,2 yoki 3 o’lchamli massivlar ko’p ishlatiladi. 2 o’lchamli massivlar shuningdek matritsa deb ham ataladi. Ko’p o’lchamli massivlarni ham bir o’lchamli massivlar kabi turli hil yo’l bilan e’lon qilishimiz mumkin:

```csharp
int[,] nums1;
int[,] nums2 = new int[2, 3];
int[,] nums3 = new int[2, 3] { { 0, 1, 2 }, { 3, 4, 5 } };
int[,] nums4 = new int[,] { { 0, 1, 2 }, { 3, 4, 5 } };
int[,] nums5 = new[,] { { 0, 1, 2 }, { 3, 4, 5 } };
int[,] nums6 = { { 0, 1, 2 }, { 3, 4, 5 } };
```

Ko’p o’lchamli massivlarning elementlarini massiv elon qilingan paytda:

```csharp
int[,] nums3 = new int[2, 3] { { 0, 1, 2 }, { 3, 4, 5 } };
```

kabi aniqlashimiz yoki sikl yordamida elon qilishimiz mumkin:

```csharp
int[,] myArr = new int[4, 5];
Random rand = new Random();

for (int i = 0; i < 4; i++)
{
    for (int j = 0; j < 5; j++)
    {
        myArr[i, j] = rand.Next(1, 30);
        Console.Write("{0}\t", myArr[i, j]);
    }
    Console.WriteLine();
}
```

Bu yerda **Random** sinfidan foydalanildi. Shuningdek massivning har bir elementini alohidadan aniqlashimiz mumkin:

```csharp
int[,] nums2 = new int[2, 3];
nums2[0, 0] = 0;
nums2[0, 1] = 1;
…
nums2[2, 3] = 5;
```

Ikki o’lchamli massivlarda \[2, 3] masivning qatorlar va ustunlar sonini belgilaydi yani 2 qatorlar soni va 3 ustunlar soni, quyida bunga misol ko’rishingiz mumkin:

```csharp
int[,] nums3 = new int[2, 3] { { 0, 1, 2 }, { 3, 4, 5 } };
```

![image](https://user-images.githubusercontent.com/81855769/123963478-f06a0300-d9cb-11eb-83ee-fdd4a184bdb4.png)

Keling endi 2 o’lchamli massivga misol ko’ramiz. Sinfxonada 3 qator partalar joylashgan, har bir qatorda 4tadan parta bor, bir partaga 1ta bola o’tiradi, oddiy hisob kitob bilan bu honada 3\*4=12 ta parta borligi va 12ta o’quvchi sig’ishini hisoblay olamiz, endi masalaga o’tamiz, matematika fanidan imtihonda barcha o’quvchilar 3,4 yoki 5 baholarini olishdi, savol sinfning o’rtacha bahosi necha?

```csharp
using System;
    class Program
    {
        static void Main(string[] args)
        {
            //3 qator 4 ustunlik 2 o'lchamli massiv elon qilamiz
            int[,] myArr = new int[3, 4];

            Random rand = new Random();

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    // random yordamida bolalarning baholarini aniqlaymiz
                    // (3,6) bu oraliqni bildiradi va 3,4,5 sonlarini o'z ichiga oladi
                    myArr[i, j] = rand.Next(3, 6); 
                    Console.Write("{0}\t", myArr[i, j]);
                }
                Console.WriteLine();
            }
            int sum = 0; //sinfning umumiy bahosi
            double average = 0.0D; //sinfnig o'rtacha bahosi
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 4; j++)
                {
                    sum += myArr[i, j];
                }
            }
            average = Convert.ToDouble(sum) / 12;
            Console.WriteLine($"Sinfning umumiy bahosi: {sum}");
            Console.WriteLine($"Sinfning o'rtacha bahosi: {average}");
        }
    }
```

Natija:

5 3 5 4

4 3 5 4

3 3 3 3

Sinfning umumiy bahosi: 45

Sinfning o'rtacha bahosi: 3,75

Massivlarning asosiy hususiyatlari:

O’lchovi(rank): massivning o’lchovini bildiradi

Massiv uzunligi(array lenght): massivning barcha elementlari soni

o'lchov uzunligi(dimension length): bir alohida o’lchovining uzunligi


# Parametrlar

Hamroliyev Ahmadjon

Biz ko’pincha metodlarda cheklangan miqdordagi argumentlardan foydalanamiz . Agar dasturdagi metodda argumentlar soni kopaysa kodning korinishini xiralashadi yani xunuklashadi. params kalit so’zi orqali biz cheksiz argumentlarni massiv korinishida kirgazishimiz va kodni ancha ixchamlashtirishimiz mumkin. params Parametrli metodlarni chaqirganimizda , biz quyidagilarni kiritishimiz mumkin:

• Massiv elementlari turiga oid argumentlarning vergul bilan ajratilgan ro'yxati:

```csharp
int yigindi = Sum(19, 9, 7, 17, 39, 47);
```

• Belgilangan turdagi argumentlar massivi:

```csharp
object[] obj = new object[] { "hamroliyev", 'a', 19, 9, 12.8 };
//Add metodini chaqiramiz.
Add(obj);
```

• Hech qanday argumentsiz. Hech qanday argument yubormasak, params ro'yxati uzunligi nolga teng boladi.

```csharp
Sum();
```

**params** kalit so’zi dasturchi metodda foydalaniladigan parametrlar soni haqida oldindan ma'lumotga ega bo'lmagan hollarda foydali bo'ladi. Metod konstruktorida params kalit sozidan faqat bir marta foydalanishimiz mumkin. params ga tegishli argumentdan keyin qoshimcha argument berish mumkin emas.

params kalit so’zidan foydalanishga oddiy misol:

```csharp
using System;
namespace dot_net_uz
{
    class Program
    {
        // params parametrni o'z ichiga olgan metod
        public static int Sum(params int[] sonlarRoyxati)
        {
            int sum = 0;
            foreach (int i in sonlarRoyxati)
            {
                sum += i;
            }
            return sum;
        }
        static void Main(string[] args)
        {
            //Sum metodini chaqiramiz.
            int [] yigindi = Sum(19, 9, 7, 17, 39, 47);
            Console.WriteLine($"yigindi : {yigindi}");
            Console.ReadKey();
        }        
    }
}
```

Output:

```
yigindi : 138
yigindi : 138
0
```

Sizda "**params** kalit so'zidan foydalanmasdan ham metodlarda massivdan foydalanish mumkinku, **params** ni nima keragi bor?" degan savol tug'ilishi mumkin. Javob shunday: **params** kalit so'zi metoddan foydalanishni ancha qulaylashtiradi:

```csharp
using System;
namespace dot_net_uz
{
    class Program
    {
        // params parametrni o'z ichiga olgan metod
        public static int Sum(params int[] sonlarRoyxati)
        {
            int sum = 0;
            foreach (int i in sonlarRoyxati)
            {
                sum += i;
            }
            return sum;
        }
        static void Main(string[] args)
        {
            int [] a={19, 9, 7, 17, 39, 47};
            int yigindi = Sum(a);     // params ishlatmasdan ham metodni bu usulda chaqirish mumkin edi
            Console.WriteLine($"yigindi : {yigindi}");
            
            // paramsdan foydalangandagina metodni shunday chaqirish mumkin:
            Console.WriteLine($"yigindi : {Sum(19, 9, 7, 17, 39, 47)}");
            
            // Agar paramsdan foydalanmagan bo'lsangiz kodning bu qismida xatolik yuzaga keladi,
            // paramsdan foydalansangiz metodni shu holatda ham chaqirish mumkin
            Console.WriteLine(Sum());
            
            Console.ReadKey();
        }        
    }
}
```

Object turidan va paramsdan foydalanish metodni har qanday turdagi va har qanday miqdordagi qabul qila olishiga imkon beradi:

```csharp
using System;
namespace dot_net_uz
{
    class Program
    {
        // params parametrni o'z ichiga olgan metod
        // object turidagi parametrlardan foydalanilgan funksiya
        public static void Print(params object[] royxat)
        {
            for (int i = 0; i < royxat.Length; i++)
            {
                // Natijalarni chop etish
                Console.WriteLine(royxat[i]);
            }
        }
        static void Main(string[] args)
        {
            object[] obj = new object[] { "hamroliyev", 'a', 19, 9, 12.8 };
            Console.WriteLine("1-usul:");
            //Print metodini chaqiramiz.
            Print(obj);
            Console.WriteLine();
            
            Console.WriteLine("2-usul:");
            //Print metodini chaqiramiz.
            Print(19,"dot-net",20,"Hamroliyev");
            
            Console.WriteLine("3-usul:");
            Print();
            Console.ReadKey();
        }        
    }
}
```

Output:

```
1-usul:
hamroliyev
a
19
9
12.8

2-usul:
19
dot-net
20
Hamroliyev
3-usul:
 
```


# Array sinfi

Mamataliyev Diyorbek

Assalomu alaykum, yosh dasturchilar! Bugun sizlar bilan **Array** abstrakt sinfiga tegishli bo’lgan bir nechta standart metod va funksiyalarni o’rganamiz. Ulardan foydalanib, bir o'lchamli massivlar ustida turli amallarni osonlik bilan bajarishingiz mumkin bo'ladi. Darsga tayyor bo'lsangiz, boshladik.

Array abstrakt sinfi System nomlar fazosida joylashgan. Bu sinf metodlariga murojaat qilish uchun **Array** kalit so’zidan keyin nuqta qo’yib, metod nomini yozamiz. Masalan, **Array.Sort(A);**

## **Array.Exists()**

Bu metod bizga massiv ichida berilgan shartga mos keluvchi element bor yoki yo’qligini aniqlab beradi. Kiruvchi parametr sifatida avvalroq e’lon qilingan bir o’lchamli massiv nomi va **lambda ifoda** kiritiladi. Lambda ifoda tekshirish uchun shart vazifasini bajaradi. Agar massivda biz bergan shartga mos keluvchi bir yoki bir nechta element mavjud bo’lsa bu metod bizga true qiymatini, aks holda false qiymatini qaytaradi. Keling, uning qanday ishlashini kodda ko’ramiz:

```csharp
using System;
namespace NewApplication
{
    class Program
    {
        public static void Main(string[] args)
        {
            int [] sonlar={2,4,6,8,11,14,15};

            if (Array.Exists(sonlar, a => a>10)) Console.WriteLine("a>10");
            else Console.WriteLine("a<10");

            if (Array.Exists(sonlar, e => e<0)) Console.WriteLine("Manfiy son bor");
            else Console.WriteLine("Manfiy son yo'q");

            if (Array.Exists(sonlar,w => w%2==0 && ((w>15)||(w<3)))) Console.WriteLine("Yes");
            else Console.WriteLine("No");

            string [] qurilmalar={"protsessor","monitor","videokarta","klaviatura"};
            Console.WriteLine(Array.Exists(qurilmalar, t => t.StartsWith("v") && t.EndsWith("a")));

            Console.ReadKey();
        }
    }
}
```

output:

```
a>10
Manfiy son yo'q
Yes
True
```

Yuqoridagi misolda ishlatilgan a, e, w o’zgaruvchilari massiv elementlarini lambda ifoda ichida ifodalash uchungina ishlatilib, kodning boshqa qismida foydalanilmagan bo’lishi kerak.

## **Array.Sort()**

Agar siz massivlarga doir masala ishlagan bo’lsangiz, massiv elementlarini o’sish tartibida tartiblash haqida bosh qotirib ko’rgan bo’lsangiz kerak. Baxtingizga, **Array** sinfida buning uchun ham tayyor funksiya bor. **Array.Sort();** qavsi ichiga e’lon qilingan massiv nomini yozsangiz kifoya. Keling, buni ham kodda ko’ramiz:

```csharp
using System;
namespace NewApplication
{
    class Program
    {
        public static void Main(string[] args)
        {
            int [] raqamlar={5,2,8,4,0,1,7};
            Array.Sort(raqamlar);
            foreach (int b in raqamlar)
            {
                Console.Write(b+" ");
            }       
             Console.ReadKey();
        }
    }
}
```

output: `0 1 2 4 5 7 8`

Nafaqat sonlarni, **string** tipidagi ma’lumotlarni ham tartiblashimiz mumkin. Bu holatda elementlar alifbo tartibida tartiblanadi:

```csharp
using System;
namespace NewApplication
{
    class Program
    {
        public static void Main(string[] args)
        {        
            string [] languages={"c#", "delphi", "paskal", "ruby", "python","c++","java","go"};
            Array.Sort(languages);
            foreach (string c in languages) {
                Console.Write(c+"; ");
            }
            Console.ReadKey();
        }
    }
}
```

output: `c#; c++; delphi; go; java; paskal; python; ruby;`

Massivning faqat bir qismini o’sish tartibida tartiblab, qolgan elementlarni o’zgarishsiz qoldirish imkoniyati ham bor. Buning uchun uchta qiymat kiritiladi: massiv nomi, tartiblash boshlanadigan indeks, tartiblanadigan elementlar soni:

```csharp
using System;
namespace NewApplication
{
    class Program
    {
        public static void Main(string[] args)
        {        
            int [] MyNewArray={3,2,6,1,9}; 

            Array.Sort(MyNewArray,2,3);            
            foreach(int a in MyNewArray){
                Console.Write(a+" ");        
            }        

            Console.ReadKey();
        }
    }
}
```

output: `3 2 1 6 9`

## **Array.IndexOf()**

Aytaylik, siz massivdagi biror elementning qaysi indeksda turishini bilmoqchisiz. Bu vazifani bajarish uchun bittagina metodni chaqirib indeksni olishingiz mumkin. Bu metodning nomi **Array.IndexOf()**. Kiruvchi parametr sifatida uning qavsi ichiga e’lon qilingan bir o’lchovli massiv nomi va qidirilayotgan element yoziladi. Agar bu element massivda mavjud bo’lsa uning massivdagi indeksi (tartib raqami) ni, aks holda -1 ni qaytaradi. Agar xohlasangiz elementni butunlay massivdan emas, uning bir qismidan ham qidirishingiz mumkin. Eslatib o’taman, massivda indekslash 0 dan boshlanadi. Keling, ko’p gapirmay shularni kodda ko’ramiz:

```csharp
using System;
namespace NewApplication
{
    class Program
    {
        public static void Main(string[] args)
        {        
            int [] MyArray={0,4,3,2,6,1,8,9,11};
            Console.Write(Array.IndexOf(MyArray,2)+"; ");    // 2 ga teng element indeksini qaytaradi

            Console.Write(Array.IndexOf(MyArray,10,3)+"; ");   /*  10 ga teng elementni 3-indeksdan boshlab oxirigacha qidiradi */

            Console.Write(Array.IndexOf(MyArray,6,1,4));   /* 6 ga teng bo'lgan elementni 1-indeksdan boshlab 4 ta elementgacha bo'lgan oraliqda qidiradi */

            Console.ReadKey();
        }
    }
}
```

output: `3; -1; 4`

## **Array.BinarySearch()**

Ana endi sizlar bilan o’sha mashxur binar qidiruv algoritmi haqida gaplashamiz. Agar massivda shu algoritm yordamida elementni qidirmoqchi bo’lsangiz, buning ham yo’li oson. Array sinfida buning uchun ham tayyor standart metod mavjud. **Array.BinarySearch()** metodi ham huddi **Array.IndexOf()** metodiga o’xshaydi. Agar kiritilgan element massivda mavjud bo’lsa shu element indeksini, aks holda biror manfiy sonni qaytaradi. Unda yana bitta metodning nima keragi bor, deb o’ylayotgan bo’lsangiz javob beraman: binar qidiruvning asosiy ustunligi uning ishlash tezligi yuqoriligida. IndexOf() metodi bilan kerakli elementni topish uchun ko’pi bilan O(n) vaqt sarflaysiz (n - elementlar soni), BinarySearch() da esa O(log2(n)) vaqt. Bu farqni tasavvur qilish uchun bir misol: 1024 ta elementga ega massivdan kerakli elementni topish uchun IndexOf() metodi O(1024) vaqt, BinarySearch O(10) vaqt sarflaydi. Ya’ni binar qidiruvning ishlash tezligi juda yuqori hamda bu farq elementlari soni ko’p bo’lgan massivlarda yaqqol seziladi.

{% hint style="info" %}
***Eslatma:*** ***BinarySearch()** metodi to’g’ri ishlashi uchun unga kiritilayotgan massiv o’sish tartibida tartiblangan bo’lishi shart !.*
{% endhint %}

Binar qidiruvni sizga shuncha maqtadim, endi kodda ham ko’raylik:

```csharp
using System;
namespace NewApplication
{
    class Program
    {
        public static void Main(string[] args)
        {        
            int [] MyArray={0,4,3,2,6,1,8,9,11};
            Array.Sort(MyArray);  //massiv {0,1,2,3,4,6,8,9,11} ko'rinishida tartiblandi
            Console.Write(Array.BinarySearch(MyArray,2)+"  ");    // 2 ga teng element indeksini qaytaradi

            Console.Write(Array.BinarySearch(MyArray,10)+"  ");   /*  10 ga teng elementni qidiradi, agar yo'q bo'lsa manfiy qiymat qaytaradi */

            Console.Write(Array.BinarySearch(MyArray,0,8,6));   /*  0-indeksdan boshlab 8 ta elementgacha bo'lgan oraliqda 6 ga teng bo'lgan elementni qidiradi */
            
            Console.ReadKey();
        }
    }
}
```

output: `2 -9 5`

## **Array.Clear()**

Massivlarda ma’lumotlarni saqlash bilan birga ularni kerak paytda o’chira olish ham kerak. Agar siz butun bir massivni yoki uning bir qismidagi elementlarni birdaniga o’chirmoqchi bo’lsangiz, bunda sizga **Array.Clear()** metodi yordam beradi. Kiruvchi parametr sifatida massiv nomi, o’chirishni nechinchi indeksdan boshlashingiz va nechta elementni o’chirishingizni kiritishingiz kerak. **Array.Clear()** metodi bilan massiv elementlari o’chirilganda massivning o’lchami o’zgarmaydi, o’chirilgan elementlar 0 (string da null) ga teng bo’lib qoladi. Masalan:

```csharp
using System;
namespace NewApplication
{
    class Program
    {
        public static void Main(string[] args)
        {        
            int [] MyArray={0,4,3,2,6,1,8,9,11};
            Array.Clear(MyArray,2,4);    // 2-indeksdan boshlab 4 ta elementni o'chirish
            foreach (int a in MyArray) {
                Console.Write(a+" ");
            }

            Console.WriteLine();

            Array.Clear(MyArray,0,9); // 0-indeksdan boshlab 9 ta elementni, ya'ni hammasini o'chirish 
            foreach (int b in MyArray) {
                Console.Write(b+" ");
            }
            Console.ReadKey();
        }
    }
}
```

output:

```
0 4 0 0 0 0 8 9 11
0 0 0 0 0 0 0 0 0
```

## **Array.Reverse()**

Bu funksiya massiv elementlarini teskari tartibda joylashtirib beradi. Masalan, {2,3,5} ko’rinishidagi massivni {5,3,2} ko’rinishiga o’tkazadi. **Array.Reverse()** ni ikki xil usulda ishlatish mumkin. Agar kiruvchi parametr sifatida faqat massiv nomi kiritilsa shu massivning barcha elementlarini teskari tartiblaydi. Yoki agar uchta parametr: massiv nomi, almashtirish boshlanadigan indeks, almashtiriladigan elementlar soni kiritilsa massivning shu qismidagina elementlarni qayta tartiblaydi.

Misol uchun:

```csharp
using System;
namespace NewApplication
{
    class Program
    {
        public static void Main(string[] args)
        {        
            int [] tub_sonlar={2,3,5,7,11,13,17,19,23,29};

            Array.Reverse(tub_sonlar);               
            foreach(int a in tub_sonlar){
                Console.Write(a+" ");
            }
            Console.WriteLine();

            Array.Reverse(tub_sonlar,2,5); 
            foreach(int b in tub_sonlar){
                Console.Write(b+" ");
            }

            Console.ReadKey();
        }
    }
}
```

output:

```
29 23 19 17 13 11 7 5 3 2
29 23 7 11 13 17 19 5 3 2
```

## **Array.TrueForAll()**

Aytaylik, sizga biror massiv berilib, savol qo’yilgan: massivning barcha elementlari musbatmi? Barcha elementlar juftmi? Barcha elementlar uzunligi 5 dan kattami? .. va hokazo. Tinib-tinchimagan dasturchilar shu holat uchun ham tayyor standart metod yozib qo’yishibdi. Ko’rdingizmi, qanchalik qulay tilni o’rganyapsiz. Ha aytgancha, metodga qaytamiz. Array.TrueForAll() metodiga kiruvchi parametr sifatida massiv nomi va lambda ifoda kiritiladi. Lambda ifoda elementlarni tekshirish uchun shart vazifasini bajaradi. Agar massivning barcha elementlari ushbu shartni qanoatlantirsa metod bizga true qiymat, aks holda, shartga mos kelmaydigan bir yoki bir nechta element mavjud bo’lsa false qiymatini qaytaradi. Yuqoridagilarni yaxshiroq tushunishingiz uchun bu funksiyaning dasturda yozilishi:

```csharp
using System;
namespace NewApplication
{
    class Program
    {
        public static void Main(string[] args)
        {        
            int [] tub_sonlar={2,3,5,7,11,13,17,19,23,29};
            Console.WriteLine(Array.TrueForAll(tub_sonlar,e => e>0));          // True
            Console.WriteLine(Array.TrueForAll(tub_sonlar,a => a%2==0));     // False
            Console.WriteLine(Array.TrueForAll(tub_sonlar,a => a%2==1));      // False

            string [] ism={"Salim", "Sardor", "Sanjar"};
            Console.WriteLine(Array.TrueForAll(ism, s => s.StartsWith("S"))?"YES":"NO");  // YES so'zi chop etiladi

            if (Array.TrueForAll(ism, w => w.Length==5)) Console.Write(5);
            else Console.WriteLine("No");                                           //  No chop etiladi
            Console.ReadKey();
        }
    }
}
```

## **Array.Resize()**

Bu funksiya massivning o’lchamini o’zgartirish uchun ishlatiladi. Kiruvchi parametr sifatida massiv nomi va yangi o’lcham kiritiladi. Natijada massivning o’lchami o’zgaradi. Qavs ichidagi massiv nomidan avval **ref** kalit so’zi yozilishi kerak. Agar massivning yangi o’lchami avvalgisidan kichik bo’lsa, elementlar massivning oxirgi elementidan boshlab to kerakli o'lchamga kelgunicha o'chiriladi. Agar yangi o’lcham eskisidan kattaroq bo’lsa, yangi elementlar massivga oxiridan qo’shilib, qiymati 0 (null) ga teng bo’ladi.

```csharp
using System;
namespace NewApplication
{
    class Program
    {
        public static void Main(string[] args)
        {        
            int [] MyNewArray={3,2,6,1,9}; 
            Array.Resize(ref MyNewArray,3);
            foreach(int a in MyNewArray){
                Console.Write(a+" ");
            }
            Console.WriteLine();

            Array.Resize(ref MyNewArray,7);
            foreach(int b in MyNewArray) {
                Console.Write(b+" ");
            }
            Console.ReadKey();
        }
    }
}
```

output:

```
3 2 6
3 2 6 0 0 0 0
```

Bu mavzudan sizga foydali nimadir o’rgata olgan bo’lsam xursandman. E’tiboringiz uchun rahmat.


# CMD argumentlari

Asronov Abdullo

Assalomu Aleykum. Bugun CMD argumentlar nimaligini ko’rib chiqamiz. CMD – so’zi “Command Prompt” inglzchadan olingan bo’lib Windows Operatsion tizimida Kommandalar ketma ketligin bajaradigan dastur. Dehqonchasiga o’zimizi konsol

![](https://user-images.githubusercontent.com/91861166/227431831-d92970d2-31dd-4449-b8b7-8ead6bd57615.png)

Hop O’zimizi konsol ekan C# ga nima aloqasi bor degan savol tug'iladi.

Siz birinchi dasturlashga kirganingizda mana bu kodga ko’zingiz tushish extimoli katta:

![](https://user-images.githubusercontent.com/91861166/227431893-fe34c439-e578-4a9c-bf63-f0e4f7ecad53.png)

Mana shu to’rtburchakka olingan string\[] args bizga dasturni ishga tushirmasdan turib qaysidir amalni bajarishga yordam beradi. Masalan:

![](https://user-images.githubusercontent.com/91861166/227432056-d719a711-c64b-4cdd-92da-213f2435e832.png)

Bu kodda “dotnet run” ni project turgan joyda konsol ochib yozasiz va dastur ishga tushadi. Biz shu ishga tushishidan oldin nima qilishini aytib yuboramiz. Misol uchun biz “dotrun run” so’zidan keyin ifni ichiga bergan shartimizni qanoatlantiradigan so’z yani “Va salom ber” so’zini yozsak bizga if sharti ishga tushadi va bizga “Dotnet salom berdi “ degan so’z paydo bo’ladi.

Natija:

![](https://user-images.githubusercontent.com/91861166/227432099-31107873-8e4a-4fb9-a5fb-50e462a45268.png)


# Obyekt va Class lar

Sobirjonov O'tkirbek

Dasturlash olamida juda ko’p yoki to’g’rirog’i eng ko’p ishlatiladigan so’zlar ushbu ikki so’zdir. Ya’ni class va object. Agar siz dasturlashni endi o’rganayotgan bo’lsangiz va class va object nima ekanligini tushunmasdan keyingi mavzularga o’tmoqchi bo’lsangiz adashasiz. Siz bu mavzuni yaxshi o’rganishingiz kerak, to’g’rirog’i juda yaxshi o’rganishingiz kerak. Ushbu mavzuda object va class larni nima ekanligi va ularning farqini ko’rsatib o’tilgan.

Demak boshladik!

1. Avvalo object va classlarni nima ekanligini bilib olaylik. Tasavvur qiling, siz g’isht zavodidasiz yoki o’zingiz (qo’lbola) g’isht quymoqchisiz.Ushbu holatda sizning g’isht quyuvchi qolipingiz bu class va siz quygan g’ishtlar esa objectlar deb qarashingiz mumkin.

![Klass (class)](https://user-images.githubusercontent.com/91861166/139823443-1e74b177-74c8-48be-a2ae-8d3b6653a684.png)

![Obyekt (object)](https://user-images.githubusercontent.com/91861166/139823902-4b5bfcb8-6fde-40ce-b2f1-52a37a2ac824.png)

Menimcha tasavvur qildingiz deb o’ylayman.

1. Siz ma’lum maqsad asosida ishlaysiz. Bu misolda esa sizning maqsadingiz nima? Albatta g’isht quyish. Demak siz g’isht quyishingizdan avval uni qolipini tayyorlab olishingiz kerak bo’ladi. Chunki qolip bo’lmasa g’ishtlar ham bo’lmaydi. Huddi shuningdek, **Class**larsiz **Object**lar ham bo’lmaydi.
2. Siz g’isht qolipni o’zingiz qilishingiz yoki tayyor yasalganini olishingiz mumkin. Tayyorini olishingizdan maqsad nima? Albatta u juda aniq o’lchamli va to’g’ri yasalgan bo’ladi. Demak siz **Class**larni yaratishingizdan avval yaxshilab o’ylab yozishingiz kerak bo’ladi. Chunki sizning g’isht qolipingiz qiyshiq va o’lchamlarida adashilgan bo’lsa siz quygan barcha g’ishtlar qiyshiq va nostandart bo’ladi.

Keling ushbu misolimizni dasturlashda ko’rib chiqamiz

![image](https://user-images.githubusercontent.com/91861166/139824677-1628e00c-83a5-498f-a04d-87b90798c609.png)

```csharp
public class BrikMold
{
  // O'lchov birliklari mm larda
  public double width = 112.5;
  public double length = 225;
  public double height = 75;
}
```

Public so’ziga hozircha uncha e’tibor bermang, uni keyingi mavzularda, Acces Modifiers mavzusida o’rganib olasiz. Class so’zi doimo yozilishi kerak chunki biz class yaratayotganimizni bildirib turadi. BrikMold (inglizcha, G’ishtQolip) – class nomi, ya’ni biz G’ishtqolipi **class**ini yozayotganimizni bildiradi. Siz buni boshqa nom bilan ham yozishingiz mumkin.

```csharp
public double width = 112.5;
public double length = 225;
public double height = 75;
```

Yuqoridagilar esa g’ishtlarning o’lchamlari, ya’ni biz yasaydigan barcha g’ishtlar shu standard asosida yaratilsin degan ma’noni bildiradi.

Bu classdan foydalanishni ko’rib chiqamiz.

```csharp
using System;
namespace ConsoleApp1
{
  classProgram
  {
    static void Main(string[] args)
    {
    BrikMold brik = new BrikMold();
    Console.WriteLine(brik.width);
    Console.WriteLine(brik.height);
    Console.WriteLine(brik.length);
    Console.ReadKey();
    }
  }
  public class BrikMold
   {
    // O'lchov birliklari mm larda
    public double width = 112.5;
    public double length = 225;
    public double height = 75;
    }
}
```

Natija :

```
112.5
75
225
```

Demak bu mavzu siz uchun tushunarli bo’ldi deb o’ylayman. Quyidagi namunalar orqali ko’proq yana o’rganishingiz mumkin. Bir-biridan farqlang, ma’nosini va ishlatilish usulini tushunishga harakat qiling. 1.

```csharp
using System;
namespace ConsoleApp1
{
  classProgram
  {
    staticvoid Main(string[] args)
    {
      BrikMold brik = new BrikMold();
      Console.WriteLine($"O'chamlari : " +
      $"{brik.width}mm , " +
      $"{brik.height}mm, " +
      $"{brik.length} mm ");
      Console.ReadKey();
    }
  }
  public class BrikMold
  {
    // O'lchov birliklari mm larda
    public double width = 112.5;
    public double length = 225;
    public double height = 75;
  }
}
```

Natija : `O'chamlari : 112.5mm , 75mm, 225 mm`

```csharp
using System;
namespace ConsoleApp1
{
  classProgram
  {
    staticvoid Main(string[] args)
    {
      GreenBrikMold brik = new GreenBrikMold();
      Console.WriteLine($"O'chamlari : " +
      $"{brik.width}mm , " +
      $"{brik.height}mm, " +
      $"{brik.length} mm " );
      Console.WriteLine($"Rangi : {brik.color}");
      Console.ReadKey();
     }
   }
   public class GreenBrikMold
   {
      // O'lchov birliklari mm larda
      public double width = 112.5;
      public double length = 225;
      public double height = 75;
      public string color = "Green";
    }
}
```

Natija :

```
O'chamlari : 112.5mm , 75mm, 225 mm
Rangi : Green
```


# Konstruktor

Shohruh Nosirov

Oddiy usullardan tashqari sinflarda **konstruktor** deb nomlangan maxsus usullar ham qo'llaniladi . Ushbu sinfning yangi ob'ekti yaratilganda konstruktorlar chaqiriladi. Konstruktorlar ob'ektni ishga tushirishni amalga oshiradilar. Ushbu sinfning yangi ob’ekti yaratilganda konstruktorlar chaqiriladi. Konstruktorlar ob’ektni ishga tushirishni amalga oshiradilar va sinflarni initsializatsiyalashga imkoniyat beradi, sinfning obyektini hosil qilganimizda, u xotiradan joy ajratadi. Ya’ni konstruktor – bu oddiy (struktura bo’yicha) funksiya, kirish ma’lumotlarini olib, sinf maydonlarini o’zlashtiradi. Konstrukto hosil qilingan har qaysi obyekt uni chaqiradi. Konstruktorlar biz biladigan metodlardan bir farqli jihati bor ekan bu esa hech qanday qiymat qaytarmaydi: na int tipi, na float tipi, na double tipini va hattoki void tipini ham.Shunaqa metod ham bularkanmi mana bularkanu. C# tilida biz agar konstruktor yozish esimizdan chiqib qoladigan bulsa o’zi jimlik buyicha sinf bitta konstruktorni yaratadi ammo u bizga kurinmaydi.Bunday konstruktorlarni **standart konstruktorlar** ham deb atashadi. Bunday konstruktorning parametrlari va tanasi yo‘q. Buni kurishingiz uchun oddiy misolni siz uchun tayorlab quydim:

```csharp
using System;

namespace HelloApp
{
    public class Talaba
    {
        public string  ismi ;
        public int yoshi ;
    } 
   class Program
    {
        static void Main(string[] args)
        {
            Talaba Shohruh=new Talaba();
        }
    }
}
```

Kurdingizmi qanday aqlli tilni o’rganayapsiz. Konstruktorni asosiy qoidalaridan biri bu konstruktorning nomi sinf nomi bilan bir xil buladi. Konstruktorlarni asosiy qolipi bir xil bulgani bilan ular parametrlarining turlar bilan( int, string) farq qilishi mumkin. Talaba nomli class yaratamiz va uning ob’ekttini hosil qilamiz.

```csharp
using System;

namespace Hello
{
public class Talaba
    {
        public string  ismi ;
        public int yoshi ;
    } 
class Program
{
    static void Main(string[] args)
    {
            Talaba a = new Talaba();

            a.ismi = "Shohruh";
            a.yoshi = 24;
        Console.ReadKey();
    }
}
}
```

Talaba ob’ektini yaratish uchun **new Talaba()** ishlatiladi. **new** operator Talaba ob'ekti uchun xotiradan joy ajratadi. Va keyin sinfda mavjud bulgan xossalar chaqirilib, ularga qiymatlar berilmoqda. a o'zgaruvchisi yaratilgan ob'ektga mos qiymatlarni xossalarga qiymatlar biriktiriladi. Agar biz ularga qiymat bermasak nima buladi degan savol tug’ilishi mumkin. Bu holat uchun ham C# bizga yechim topgan bundan havotir olmasak ham buladi.Agar xossalarimiz raqamli turda buladigan bulsa 0 ni oladi, satrlilar uchun esa null(yani hech qanday qiymat mavjud emas) ni oladi. Endi konstruktorlarni o’zimiz ham yaratib kuraylikchi. Shu bilan birga bir biridan farq qiladigan konstruktorlani ham kursatib o’tib ketaman.Unda keying misolga etibor bilan qarang.Yuqorida , ob’ektni ishga tushirish uchun standart konstruktor ishlatilgan . Biroq, biz o’zimiz konstruktorni aniqlaymiz.

```csharp
class Person
{
    public string name;
    public int age;

    public Person() { name = "Nomalum"; age = 18; }      // 1-konstruktor

    public Person(string n) { name = n; age = 18; }         // 2 -konstruktor

    public Person(string n, int a) { name = n; age = a; }   // 3 -konstruktor

    public void GetInfo()
    {
        Console.WriteLine($"Name: {name}  Age: {age}");
    }
}
```

Endi sinf 3 ta konstruktorni aniqlaydi, ularning har biri har xil parametrlarni qabul qiladi vas inf maydonlarining qiymatlarini belgilaydi. Endi shu konstruktorlardan foydalanib kuraylikchi nima bularkan.

```csharp
static void Main(string[] args)
{
    Person Ali = new Person();              // 1-konstruktor chaqirilyapdi
    Person Vali = new Person("Vali");          //2-konstruktor chaqirilyapdi 
    Person Gani = new Person("G’ani", 25);   // 3-konstruktor chaqirilyapdi 


    Ali.GetInfo();             // Name: Nomalum  Age: 18
    Vali.GetInfo();           // Name: Vali  Age: 18
    Gani.GetInfo();          // Name: G’ani  Age: 25
}
```

Yana bir qoidamiz bor, agar sinfda konstruktorlar yaratilgan bulsa , ulardan birini aniq ishlatishimiz kerak ekan. Menimcha C# mehnatni qadrlaydigan til menimcha shuncha konstruktor yaratganingdan keyin hech bulmasa bittasini ishlatgin demoqchi shekilli. Sizlarga bir yangilikni ham aytib utmoqchiman C# 9.0 dan boshlab biz konstruktor chaqirayotganimizda new dan sung sinf nomini yozishimiz shart emas ekan. Masalan mana bunday qilib:

```csharp
Person Ali=new ();                             //     Person Ali = new Person();   degani
Person Vali=new(“Vali”);                  //     Person Vali = new Person("Vali");         
Person G’ani =new (“G’ani”, 25);     // Person G’ani = new Person("G’ani", 25);
```

Shu bilan konstruktorni ham bilib oldik darslarimiz qiziq ketayapdi degan umiddaman. Hali oldinda bizni qizg’in darslar kutib turibdi.


# Obyektni ishga tushiruvchilar

Zohidbek Mengliboyev

Yaxshi! Bundan avvalgi mavzuda biz konstruktorlar haqida bilib oldik. Bilasizki, biz obyektni ishga tushirish va uni C# da dastlabki holatga keltirish uchun konstruktordan foydalanamiz. Obyektni initsializatsiya qilishning yana bir yo'li mavjud va u obyektni ishga tushiruvchilar(object initializers) vositasidan foydalanadi. Bu ficha C# 3.0 yoki undan yuqori versiyalarida kiritilgan. Obyektni ishga tushiruvchi(object initializer) - bu oddiy sintaksis yoki obyektni uning konstruktorlaridan birini chaqirmasdan tezda ishga tushirish. Xo’sh, bu bizga bir nechta yoki undan ko’p konstruktorlarni tuzishdan qochish uchun kerak. Keling, bir misol keltiraman. Tasavvur qiling-a, bizda bu inson sinfi ko'p maydonlarga ega. Endi bu juda oddiy misol. Bu yerda faqat to‘rtta maydonimiz bor. Haqiqiy yirik loyihalarda sizda yana bir nechta maydonlar bo'lishi mumkin:

```csharp
public class Inson
{
    public int Id;

    public string Ismi;

    public string Familiyasi;

    public DateTime Tavalludkuni;
}
```

Endi ushbu sinf bilan, agar siz turli maydonlarni initsializatsilash uchun konstruktorlar tuzmoqchi bo'lsangiz, siz shunday sinfga ega bo'lishingiz mumkin:

```csharp
public class Inson
{
    public Inson(int id) { } // 1-kontruktor

    public Inson(int id, string ismi) { } // 2-konstruktor

    public Inson(int id, string ismi, string familiyasi) { } // 3-konstruktor

    public Inson(int id, DateTime tavalludkuni) { } // 4-konstruktor
	  
	  ........
}
```

Ko'rib turganingizdek, menda 4 ta konstruktor bor. Birinchisi faqat ID olad. Ikkinchisi ID va ism oladi. Uchinchisi id, ism, famiyani oladi va hokazo. Shunday qilib, siz juda ko'p turli xil kombinatsiyalarni ko'rasiz. Aynan shuni biz obyektni ishga tushiruvchilarni tanishtirmasimizdan oldin C# da shunday qilar edik. Ko'rib turganingizdek, bunday kod yozish tartibsiz va osongina nazoratdan chiqib ketadi. Shunday qilib, obyektni initsializatsilash muammosini hal etish uchun obyektni ishga tushiruvchilar maydonga keladi. Bunda bu konstruktorlarning hech biri kerak bo’lmaydi. Masalan, bunday:

```csharp
var inson = new Inson
{
    Ismi = "Zohidbek",
    Familiyasi = "Mengliboyev"
};
```

Men Inson sinfining konstruktorlaridan birini chaqirmayapman. Bu yerda ko'rib turgan sintaksis biz obyektni ishga tushiruvchi sintaksisi deb ataladigan narsadir. Shunday qilib, siz asosan xususiyatlar nomini belgilaysiz va ularga boshlang'ich qiymatni tayinlaysiz. Shuni esda tutingki, bunday obyektni qachon ishga tushirish kerak degan so'zlar orqasida standart yoki parametrsiz konstruktor chaqiriladi. Va keyin siz bu yerda o'rnatgan barcha xususiyatlar ishga tushiriladi. Shunday qilib, biz konstruktorlarni zarur hollarda kerak bo'lgan ssenariylar uchun ularni zaxiraga olib qo'yishimiz mumkin.


# Destructor

Suxrob Xayitmurodov

Destructor - bu shunday member funksiyaki, ortiq kerak bo'lmaydigan classlarni destroy (o'chirish) qilishga imkon beradi. Ya'ni bir necha bor ishlatilingan classlarga bizning boshqa ehtiyojimiz bo'lmasa, uni destroy qiladi. Bu method .NET Framework Garbage collectoridan bilvosita chaqiriladi va shu sababli dasturchiga uni chaqirishga (invoke) aslo hojat qolmaydi. Qachonki o'zgaruvchilar va ob'ektlar (objects) reachable (erishish mumkin bo'lmasa -- bu yerda o'zgaruvchi va ob'ektlarni ishlata olishimiz nazarda tutilayapti ;) ) bo'lmasa, ularni destruct (o'chirish) qilishimiz mumkin.

![Constructor](/files/-Meu-sWrCWmLOmj5lQ19)

Agar shundayam tushunmagan bo'lsangiz, unda sodda tilda tushuntiraman, Constructor qandaydir vazifani build (qurish)bajarishga asoslangan method bo'lsa, Destructor destroy (buzish) qilishga asoslanadi.

![Bu destructor, qarang buzayapti :(](/files/-Meu02hu2jO8oZBaC3yY)

### Shularni bilmasangiz bo'lmaydi!

* Har bir classda destructorlarni bir marta e'lon qilish mumkin
* Bu method qiymat qaytarmaydi (return) va classning nomi bilan bir xil nomlanadi
* Bu method [constructor](https://docs.dot-net.uz/c-.net/basic/essential/konstruktor)lardan alohida ajratib olingan method, sababi uni nomlashda oldiga Tilda symbol (\~) qo'yiladi
* Destructor gitara narsa, unga na [parametr](https://docs.dot-net.uz/c-.net/basic/essential/parametrlar), na [access modifier](https://docs.dot-net.uz/c-.net/basic/essential/modifikatorlarga-ruxsat-berish) kerak
* Destructorlar [structure](https://docs.dot-net.uz/c-.net/basic/essential/struct)larda ishlamaydi, faqatgina classlarga xos bo'lgan method
* [Overload (qayta yuklash)](https://docs.dot-net.uz/c-.net/basic/essential/overload-qayta-yuklash) yoki [inherit (voris)](https://docs.dot-net.uz/c-.net/basic/essential/vorislik) qilinmaydi
* Ob'ektning base classida destructor Finalize method (dasturni tugallash methodi) sifatida chaqiriladi

```csharp
class NimaGap
{ 
   // Bir nechta ishlar
   // O'zgaruvchi o'zgarmas va boshqalar

   // Destructor
   ~Misol()
    {
        // Yana qandaydir kodlar
    }
}
```

### **Misol**

```csharp
using System;
class Program
{
     static void Main(string[] args)
     {
         int yil = int.Parse(Console.ReadLine());

         Details();
         GC.Collect();
         Console.ReadLine();

     }
     public static void Details()
     {
         User user = new User();
     }
}

class User
{
     public User()
     {
         Console.WriteLine("Created");
     }
     ~User()
     {
         Console.WriteLine("Destroyed");
     }
}
```

```csharp
OUTPUT:
    inputdan so'ng
    Created
    Destroyed
```

Bu misolda, destructor nima ekanligini va qanday ishlashini ko'rdik!


# this

Shohruh Nosirov

Biz bilamizki, obyektlarga initsializatsiya(qiymat belgilash) konstruktor orqali hosil qilinadi. Har qaysi yaratilgan obyekt parametrning aniq bir qiymatini qabul qiladi. Demak hozircha oddiy classni kurib turamiz.

```csharp
class p
{
    // Xossa (avtomatik)
    public int x { get; set; }
    public int y { get; set; }
    // Konstruktorlar
    public p()
    {
    }
    public p(int v1, int v2)
    {
        x = v1;
        y = v2;
    }
}
```

\
Bu dasturda nima jarayon ketayotganini bilsangiz kerak agar bilmasangiz qisqacha yana tushuntirib o’tib ketaman. Demak diqqat qilamiz!.

Biz **p** nomli class yaratdik. Unda 2 ta xossa: **x** va **y** va qo'shimcha tarzda yana 2 ta konstruktor ham bor. Sizda savol tug’ilgan bo'lishi mumkin:

{% hint style="info" %}
**Birinchi konstruktor nega yaratildi, u hech qanday vazifa bajarmayabdi?**
{% endhint %}

Men bunga qisqacha javob beraman. Agar biz dasturda qo'shimcha konstruktor yaratmasak jimlik bo'yicha (yani yaratmasak ham uzi bitta konstruktor mavjud bo'ladi) yaratilgan buladi. Bu holatda esa biz yana bitta konstruktor yaratdik. Unda 2 ta argument mavjud (argument deganlarim v1 va v2 lar) va u 2 ta xossaga qiymat taminlash amalini bajaryabdi.

Bu jarayonni tushundingiz degan umiddaman. Demak konstruktorni vazifasini tushunib oldik endi esa, **this** ning nima vazifa bajarishini tushuntirib o'taman. Buning uchun biz yana xuddi shu classni qaytadan yozamiz.

```csharp
class p
{
    // Xossa (avtomatik)
    public int x { get; set; }
    public int y { get; set; }
    // Konstruktorlar
    public p()
    {
    }
    public p(int x, int y)
    {
        x = x;
        y = y;
    }
}
```

\
Bu yerda avvalgi classdan farqi 2-konstruktorga 2 ta argument nomlari class xossalarining nomlari bilan bir xil bo'lib qoldi. **this** xuddi shu holatda kerak. Ya'ni, agar biz konstruktorda xossaning nomlaridan argument sifatida foydalansak shu kalit so’zdan foydalanmiz. Ammo, sizda “nega unday qilayabmiz” degan savol tug’ilgan bulishi mumkin albatta. Agar, **this** dan foydalanmasak konstruktorda xossaga qiymat berishda nizolar kelib chiqishi mumkin (ya'ni xatoliklar) . Bu yerda huddiki xossaga o'ziga-o'zini ta'minlaganday bo'lib qoladi. this dan foydalanishni quyidagi misolda ko'rishingiz mumkin.

```csharp
class p
{
    // Xossa (avtomatik)
    public int x { get; set; }
    public int y { get; set; }
    // Konstruktorlar
    public p()
    {
    }
    public p(int x, int y)
    {
        this.x = x;
        this.y = y;
    }
}
```

\\

Endi hech qanday xatoliklar bo'lmaydi this.x bu o'sha classdagi xossa deb hisoblanadi x ni uzi esa konstruktordagi argument sifatida qabul qilinadi. Keyingi qatorda ham xuddi shu xolat bajariladi. Konstruktorda classning xossa nomlaridan foydalanish yaxshiroq. Chunki ba'zi xossalar **private** (yani faqat shu classni ichida foydalanish mumkin) bo'lsa, o'sha classni obyektini yaratgan paytimiz unga konstruktor orqali qiymat bera olamiz.

Xulosa qilib aytganda, agar biz konstruktorda argumentlarni nomlashda xossa nomlaridan foydalansak, **this** dan foydalanar ekanmiz xolos. this haqida ma'lumotga ega bo'ldingiz degan umiddaman. Bu kodlarni albatta o’zingiz ham sinab kuring.


# static

Sobirjonov O'tkirbek

Static Class va static funksiyalar

Siz C# da dastur yozar ekansiz, **static** kalit so’ziga duch kelishingiz aniq. Ushbu darsda **static** kalit so’zi *class*lar yaratishda qanday ahamiyatga ega ekanligini ko’rib chiqamiz.

*Class*larning oldidan **static** so’zi yozilgan bo’lsa, demak bu *class* - **static** *class* degan ma’noni bildiradi. **Static** *class*lar bizga object olmasdan uning maydon, method va property laridan foydalanish imkoniyatini beradi.

`Console.WriteLine(Math.PI);`

Ushbu code dagi **Math.PI**ga e’tibor bering. **Math** class – bu **static** qilib yozib chiqilgan *class*dir.\
Static qilib siz birorta *class* yaratsangiz undan object olmasdan `ClassName.PropertyName` yoki `ClassName.MethodName` ko’rinishida ishlatish imkoniyati bo’ladi (Class nomi “.” dan keyin ishlatmoqchi bo’lgan maydon va method nomini yozib ishlatib keta olasiz).

**static** *class* lar qanday yoziladi? Quyidagi namunada **Math** *class*idagi **PI** ni ishlatishni qo’lda yozib chiqsak qanday ko’rinishda bo’lishini ko’rib chiqamiz.

```csharp
using System;  
namespace ConsoleApp1 
{ 
  class Program 
  { 
    static void Main(string[] args) 
    { 
        Console.WriteLine(Numbers.PI); 
    } 
  } 
 
  public static class Numbers 
  { 
    private static double _pi = 3.14; 
 
    public static double PI 
    {  
        get
        { 
            return _pi; 
        }  
    } 
  } 
} 
```

Demak, **static** *class*larni yaratish uchun class nomi va method nomlari oldidan **static** kalit so’zini ishlatgan holatda yarata olar ekanmiz. Static classlarda object olib bo’lmaydi, chunki bu xususiyat object olmasdan ishlatish uchun qo’shilgan. Static classlar va static methodlar haqida quyidagi namudan xulosa olishingiz mumkin.

```csharp
using System;  
namespace ConsoleApp1 
{ 
  class Program 
  { 
    static void Main(string[] args) 
    { 
        int number1 = 2; 
        int number2 = 5; 
        int number3 = 6; 
        int number4 = 7; 
        Console.WriteLine(PrimeNumbers.IsPrime(number1)); 
        Console.WriteLine(PrimeNumbers.IsPrime(number2)); 
        Console.WriteLine(PrimeNumbers.IsPrime(number3)); 
        Console.WriteLine(PrimeNumbers.IsPrime(number4)); 
        Console.ReadKey(); 
      } 
  } 
 
  public static class PrimeNumbers 
  { 
    public static bool IsPrime(int number) 
    { 
        bool isPrime = true; 
        if (number < 2) return false; 
        for (int i = 2; i < Math.Sqrt(number); i++) 
        { 
            if(number % i == 0) 
            { 
                isPrime = false; 
                break; 
            } 
        } 
        return isPrime; 
     } 
  } 
} 
```

Natija :

```
True 
True 
False 
True
```


# Struct

Niyozbek Mirzayev

Dasturlashga endi kirib kelganlar orasida turli xil yangi atamalarga duch kelish oddiy holat. Shu atamalardan biri bu **Struktura** yoki ingliz tilda **Struct**dir.

C# dasturlash tilida (boshqa dasturlash tillarida ham) ma'lumotlar ikki xil bo'ladi: **value type** va **reference type**.

**Value type** tipidagi ma'lumotlar xotirada o'zi ma'lum joy egallab, qiymati yozilgan holda saqlanadi. Bu tipga misol qilib oddiy tiplar: *int, double, char, string, boolean* kabilarni, bundan tashqari **struct**ni ham keltirishimiz mumkin. **Struktura** o'zi ham value type hisoblanadi va value type dagi ma'lumotlarni jamlangan holatda saqlash uchun ishlatiladi. value type turidagi ma'lumotlar **stack** xotirada saqlanadi.

**Reference type**dagi ma'lumotlar esa xotirada saqlanganda o'zi bilan birga qiymatini olib yurmaydi, ular shunchaki xotirada boshqa ma'lumot yozilgan manzilga ko'rsatkich (havola)ni o'zida saqlaydi. Reference typega *classlar, interfacelar, delegatlar, massivlar* misol bo'la oladi. Reference type turidagi ma'lumotlar **heap** xotirada saqlanadi.

Struktura bir nechta o'zaro bog'liq ma'lumotlarni ular orasidagi mantiqiy bog'liqlikni ta'minlagan holda saqlash imkoniyatini beradi. Strukturani tushunishdan avval, undan foydalanmagan holda talabalar haqidagi ma'lumotlarni saqlashga urinib ko'raylik. Bu holatda talabalarga tegishli har bitta ma'lumotni yangi o'zgaruvchiga yuklashimizga to'g'ri keladi:

```csharp
string ism = "Dave";
string familiya = "Thompson";
int yosh = 17;

string ism2 = "Jef";
string familiya2 = "Harrison";
int yosh2 = 23;
```

Lekin bir muammo bor, foydalanuvchilar soni ko'paygani sari har bir foydalanuvchining ma'lumotlarini boshqalari bilan chalkashishini ko'rishimiz mumkin. Sababi ma'lumot ko'p va har bir foydalanuvchining ma'lumoti bir-biriga mantiqiy tomondan bog'lanmagan.

Shu payt Struktura bizga yordamga keladi. U har bir foydalanuvchining ma'lumotlarini xotirada alohida saqlaydi va mantiqan bog'lab beradi. Bu o'z o'rnida dasturchiga qulaylik yaratadi.

Misol uchun yuqoridagi kod Struktura yordamida quyidagi ko'rinishga keladi:

```csharp
foydalanuvchi1
{
   string ism = "Dave";
   string familiya = "Thompson";
   int yosh = 17;
};

foydalanuvchi2
{
   string ism = "Jeff";
   string familiya = "Harrison";
   int yosh = 23;
};
```

**Keling, C# dasturlash tilida Struktura qanday ishlatilishini ko'rib chiqamiz.**

Birinchi o'rinda Struktura yaratish **struct** kalit so'zini yozish bilan boshlanadi, shundan so'ng, uning nomi va uning xususiyatlarni e'lon qilishimiz lozim. Misol uchun, **Talaba** nomli Struktura quyidagicha ko'rinishga ega bo'ladi:

```csharp
struct Talaba
{
    public string ism;
    public string familiya;
    public int yosh;
}
```

Talaba Strukturasini huddi qolip kabi tasavvur qiling. Lekin sezganingizdek biz faqat qolip yasadik. Undan hali birorta ham o'zgaruvchi yaratganimiz yo'q. Shu qolip asosida o'zgaruvchi yaratish uchun:

```csharp
Talaba talaba1 = new Talaba();
```

ko'rinishida dasturning Main qismida e'lon qilamiz. Uni ma'lumotlar bilan to'ldirish uchun yaratilgan o'zgaruvchini chaqirish, shundan so'ng uni ma'lum xususiyatlar bilan to'ldirish lozim. Buni quyidagicha ko'rsangiz bo'ladi:

```csharp
talaba1.ism = "Dave";
talaba1.familiya = "Thompson";
talaba1.yosh = 17;
```

Kiritilgan xususiyatlarni Consoleda chiqarish uchun quyidagi funksiyadan foydalanish kifoya.

```csharp
Console.WriteLine(talaba1.ism)
Console.WriteLine(talaba1.familiya)
Console.WriteLine(talaba1.yosh)
```

Natija quyidagi ko'rinishda bo'ladi:

```
Dave
Thompson
17
```

Strukturada ochiq xususiyatlaridan tashqari yashirin xususiyatlarga ham ega bo'lishi mumkin. Buning uchun xususiyatlarni konstruktorda e'lon qilish davomida **public (ommaviy)** o'rnida **private (shaxsiy)** operatoridan foydalanamiz. Bu hodisani quyidagi kodda, **yosh** public xususiyatini private xususiyatga o'zgartishi orqali ko'rishimiz mumkin:

```csharp
struct Talaba
{
    public string ism;
    public string familiya;
    private int yosh;
}
```

Hozirdan boshlab talabaning yoshini dasturda ishlata olmaymiz. Lekin, ma'lumotni ishlata olmasak nima keragi bor, to'g'rimi?

Shu sababdan shu kabi yashirin xususiyatlarni namoyon qilish yoki ularga qiymat berish uchun maxsus funksiyalar - **event**lar e'lon qilishimiz mumkin. Shunday qilsak, dasturning Main qismida talabaning bu xususiyatiga faqatgina shu **event** orqali murojaat qilish mumkin bo'ladi. Bunday usulda ulanish ma'lumotlar bexosdan o'zgarib ketishini oldini oladi. Misol uchun talabaning faqatgina yoshini ko'rsata oladigan Event quyidagicha bo'ladi:

```csharp
struct Talaba
{
	public string ism;
	public string familiya;
	private int yosh;

	public int GetAge()
	{
		return yosh;
	}
}
```

Quyida foydalanuvchi yoshini e'lon qiluvchi va uni Consoleda chiqaruvchi Eventlar va Strukuraning to'liq ko'rinishi:

```csharp
using System;

namespace Struktura
{
	internal class Program
	{
		static void Main(string[] args)
		{
			//talaba strukturasidan o'zgaruvchi yasash
			Talaba talaba1 = new Talaba();

			//ochiq xususiyatlarga qiymat berish
			talaba1.ism = "Dave";
			talaba1.familiya = "Thompson";

			//foydalanuvchining taxminiy yoshini kiritish
			int yosh = 17;

			//olingan qiymatni Eventga yuborish
			talaba1.PutAge(yosh);

			//private xususiyani Event orqali Consolega chiqarish
			talaba1.GetAge();

		}
	}

	//Struktura
	struct Talaba
	{
		//ochiq xususiyatlar-public properties
		public string ism;
		public string familiya;

		//yashirin xususiyatlar-private properties
		private int yosh;

		//yashirin xususiyatni(yosh) ko'rsatuvchi Event
		public void GetAge()
		{
			Console.WriteLine(yosh);
		}

		//Yashirin xususiyatga(yosh) qiymat beruvchi Event
		public void PutAge(int age)
		{
			yosh = age;
		}
	}
}
```

Consoleda natija quyidagicha bo'ladi:

```
17
```

Bundan tashqari, **event**lar yordamida o'zgaruvchiga qiymat berishda ma'lum shartlar qo'yish, qo'shimcha amallar bajarish mumkin. Masalan, odatda talabaning yoshi eng kamida 17 yosh bo'ladi deb hisoblasak, yosh o'zgaruvchisiga bundan kichik qiymat berish mumkin bo'lmasin:

```csharp
using System;

namespace Struktura
{
	internal class Program
	{
		static void Main(string[] args)
		{
			
			Talaba talaba1 = new Talaba();			
			talaba1.ism = "Dave";
			talaba1.familiya = "Thompson";		
			talaba1.PutAge(3);  
			//talabaning yoshi 3 ga teng bo'lolmagani uchun, bu talabaning yoshi 17 deb belgilanadi
			
			talaba1.GetAge();
			
			Talaba talaba2 = new Talaba();			
			talaba2.ism = "Jeff";
			talaba2.familiya = "Harrison";		
			talaba2.PutAge(23);			
			talaba2.GetAge();

		}
	}

	//Struktura
	struct Talaba
	{		
		public string ism;
		public string familiya;		
		private int yosh;		
		public void GetAge()
		{
			Console.WriteLine(yosh);
		}
		public void PutAge(int age)
		{
			if (age>16) yosh = age;
			else yosh=17;
		}
	}
}
```

Natija:

```
17
23
```

Ko'rib turganingizdek, **event**lar ma'lumotlar ustidan nazorat qilib turishimizni osonlashtiradi.


# Enum

Xakimbekov Doniyor

**enum** - bu o’zgarmaslarni ifodalovchi maxsus “sinf” (qiymati **o’zgarmaydigan** yoki bir so’z bilan aytganda **read-only** o’zgaruvchilar). **enum** ni yaratish uchun **enum** kalit so’zidan foydalanamiz (interfeys yoki sinf o’rniga) va enum elementlari vergul bilan ajratib yoziladi:

**enum** ni yaratish uchun ***enum*** kalit so’zidan foydalanamiz (interfeys yoki sinf o’rniga) va **enum** elementlari *vergul* bilan ajratib yoziladi

**Misol uchun:**

1.

```csharp
using System;
namespace NewApplication
{
    enum Level 
    {
      Low,
      Medium,
      High
    }
}
```

**enum** elementlariga nuqta sintaksisi bilan kirishingiz mumkin:

```csharp
Level myVar = Level.Medium;
Console.WriteLine(myVar);
```

{% hint style="info" %}
*enum* so’zi bu “*enumerations*” qisqartmasi bo’lib “maxsus sanab o’tilgan” degan ma’noni anglatadi.
{% endhint %}

Siz **enum** kalit so'zidan Class ichida ham foydalana olasiz: Misol uchun:

```csharp
classProgram
{
  enumLevel
  {
    Low,
    Medium,
    High
  }
static void Main(string[] args)
{
  Level myVar =Level.Medium;
  Console.WriteLine(myVar);
}
```

Console: `Medium`

**enum** qiymatlari: Odatda, **enum** ning birinchi qiymati doim “0” dan boshlanadi va shu tariqa ikkinchisi “1” bo’lib davom etadi…

Elementdan butun qiymat olish uchun elementni *int* ga o’zgartirishimiz (convert) kerak: Misol uchun

```csharp
enumMonths
{
  January,// 0
  February,// 1
  March,// 2
  April,// 3
  May,// 4
  June,// 5
  July// 6}
static void Main(string[] args)
{
  int myNum =(int)Months.April;
  Console.WriteLine(myNum);
}
```

Console: `3`

Shuningdek, siz o’zingizni enum qiymatlaringizni belgilashingiz ham mumkin va keyingi elementlar raqamni mos ravishda yangilaydi. Misol uchun:

```csharp
enumMonths
{
  January,// 0
  February,// 1
  March=6,// 6
  April,// 7
  May,// 8
  June,// 9
  July// 10}
staticvoidMain(string[] args)
{
  int myNum =(int)Months.April;
  Console.WriteLine(myNum);
}
```

Console: `7`

**enum** ko’pincha mos qiymatlarni tekshirish uchun switch ichida foydalaniladi. Misol uchun

```csharp
enumLevel
{
  Low,
  Medium,
  High
}
static void Main(string[] args){
Level myVar =Level.Medium;
switch(myVar)
{
  caseLevel.Low:
  Console.WriteLine("Low level");
  break;
  caseLevel.Medium:
  Console.WriteLine("Medium level");
  break;
  caseLevel.High:
  Console.WriteLine("High level");
  break;
}
```

Console: `Medium level`

**enum** nima uchun va qachon ishlatiladi?

Oy kunlari, kunlar, ranglar, kartalar toʻplami va h.k. kabi oʻzgarmas qiymatlarga ega boʻlganingizda enum dan foydalaning.

**Enum** ni tushinish uchun quyidagi misolda ko'raylik Misol: Bizga hafta kunlari (1,2…7)gacha raqamlar bilan raqamlab berilgan bo'lsin bizga hafta raqami berilsa hafta kunini chiqaradigan dastur qilishimiz kerak. Bu masalani birinchi biz bilgan switch case da hal qilib ko'raylik.

```csharp
using System;
namespace switch_case
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hafta raqamini kiriting :");
            int n=int.Parse(Console.ReadLine());
            switch(n)
            {
                case 1:Console.WriteLine($"Dushanba");break;
                case 2:Console.WriteLine($"Seshanba");break;
                case 3:Console.WriteLine($"Chorshanba");break;
                case 4:Console.WriteLine($"Payshanba");break;
                case 5:Console.WriteLine($"Juma");break;
                case 6:Console.WriteLine($"Shanba");break;
                case 7:Console.WriteLine($"Yakshanba");break;
            }
        }
    }
}
```

Endi bu masalani **enum** bilan hal qilib ko'ramiz

```csharp
using System;
namespace enum1
{
    class Program
    {
        public enum Kun
        {
            Dushanba=1, Seshanba=2, Chorshanba=3,Payshanba=4, Juma=5, Shanba=6, Yakshanba=7
        };
        static void Main()
        {
            Console.WriteLine("Kun raqamini kiriting =>");
            
            int n= int.Parse(Console.ReadLine());
            
            System.Console.WriteLine(Enum.GetName(typeof(Kun),n));
            
        }
    }
}
```

**Enum** orqali kodni uzunligi ancha qisqardi.

Quyidagi hollarda **enum** elementlarga avtomatik qiymat beradi.

```csharp
using System;
namespace _enum
{
    class Program
    {
        public enum ranglar
        {
            qizil,  //0
            sariq,  //1
            yashil = 4,
            kok,    //5
            qora    //6
        };
        static void Main(string[] args)
        {
            string[] rang = Enum.GetNames(typeof(ranglar));
            foreach(var r in rang)  // bu yerda ranglar nomi chop etilmoqda
            {
                Console.WriteLine(r);
            }
            int[] values =(int[]) Enum.GetValues(typeof(ranglar));
            foreach(var m in values) //bu yerda esa qiymati
            {
                Console.WriteLine(m);
            }
        }
    }
}
```

Qora oynada quyidagicha natija chiqadi.

```
qizil
sariq
yashil
kok
qora
0
1
4
5
6
```

Biz **enum** dan foydalanib avtomobillar narxi chiqaruvchi dastur tuzib ko'rayik.

```csharp
using System;
namespace car
{
    class Program
    {
        enum mashinalar
        {
            Nexia3 = 87000000,
            Gentira = 100000000,
            Cobalt = 97000000,
            Spark=76000000,
            Damas=66000000,
            Malibu=275000000,
            Kaptiva=260000000,
        }
        static void Main(string[] args)
        {
            Console.WriteLine(mashinalar.Malibu+"ning narxi");
            int narxi = (int)mashinalar.Malibu;
            Console.WriteLine(narxi + " so'm");
        }
    }
}
```

Qora oynadagi natija:

```
Malibuning narxi
275000000 so'm
```

**Enum** elementlarini qiymatiga qarab jop etish.

```csharp
using System;
namespace dasturlash
{
    class Program
    {
        enum dasturlash_tillari
        {
            Csharp=1,
            C,          //2
            Cplasplas,  //3
            Go,         //4
            Python,     //5
            Java,       //6
            JavaScript, //7
            Kotlin,      //8        
        }
        static void Main(string[] args)
        {
            int i = 1, j = 4, k = 5, f = 8;
            dasturlash_tillari a1, b1, c1, d1;
            a1 = (dasturlash_tillari)i;
            b1 = (dasturlash_tillari)j;
            c1 = (dasturlash_tillari)k;
            d1 = (dasturlash_tillari)f;
            Console.WriteLine(a1);
            Console.WriteLine(b1);
            Console.WriteLine(c1);
            Console.WriteLine(d1);
        }
    }
}
```

Qora oynadagi natija

```
Csharp
Go
Python
Kotlin
```


# Property va Field lar

Asronov Abdullo

Field- Bu so'zni o'zbekchaga tarjima qilsak **MAYDON** degan ma'noni beradi. Lekin bizda C# Field nima, uni qayerda ishlatishiz mumkin, kabi savollar tug'ilishi mumkin.

C# dasturlash tilida Field bu to'g'ridan-to'g'ri "Class" yoki "Strukturada" e'lon qilingan har qanday turdagi o'zgaruvchidir; Ya'ni Classning ichidagi har qanday tipdagi o'zgaruvchi.

Field asosan ma'lumot saqlashga ishlatiladi. Ko'p hollarda fieldni private(yani Classning shaxsiy o'zgaruvchisi) holda ochiladi va bu fielddan biz faqat "Class" ning ichida foydalana olamiz . Aniqrogi shu classdan obyekt olinganda unga to'gridan to'gri murojat qila olmaymiz. Lekin boshqa tiplarda ham ochish mumkin; bu haqda keyingi Modifikatorlarga ruxsat berish mavzusida aniqroq tushunib olasiz.

Keling sizlar bilan Field ga oid bir misol kurib chiqamiz:

```csharp
using System;

namespace Field
{
    public class Program
    {
        public static void Main(string[] args)
        {
            AboutField aboutField = new AboutField();
            aboutField.Firstname = "Abdulloh";
            aboutField.LastName = "Asronov";
            aboutField.Age = 25;
            aboutField.Printing();

        }
    }
    public class AboutField
    {
        public string Firstname;
        public string LastName;
        public int Age;
        
        public void Printing()
        {
            Console.WriteLine(Firstname + " " + LastName + " " + Age);
        } 
    }
}
```

Property ga keladigan bulsak u **Xususiyat** degan ma'noni bildiradi.

Uning Asosiy vazifasi malumot tashishdan iborat.

Property(Maydon) get(o'qishi), set(yozishi) yoki private fieldan malumot olishda ishlatish mumkin.

Get property qiymatini qaytarish uchun set esa yangi qiymat belgilashga xizmat qiladi.

Tassavvur qiling tepada aytib o'tganimizdek private faqat o'zi ochilgan class ichida foydalana olamiz. Agar uni qiymatini qolmoqchi bo'lsak quyidagi tarzda Propertyga yuzlanamiz:

```csharp
using System;

namespace Field
{
    public class Program
    {
        public static void Main(string[] args)
        {
            AboutProperty aboutProperty = new AboutProperty();
            Console.WriteLine(aboutProperty.FirsName);

        }
    }
    public class AboutProperty
    {
        private string firsname = "Abdullo";
        public string FirsName
        {
            get
            {
                return firsname;
            }
            set
            {
                firsname = value;
            }

        }
       
    }
}
```

Yuqorida private fielddan propertyga uni qiymati olinib Firstname Propertysiga yozilmoqda va biz buni tashqarida ishlatish imkoniga ham ega bo'lyabmiz. Umid qilamanki bu sizga foydali bo'ldi!


# Vorislik

Xushnazarov Faxriddin

Vorislik (inheritance) Obyektga Yonaltirilgan Dasturlash(OYD)ning muhim tamoyillaridan biridir. Voris orqali bir sinf boshqa sinfning funksionalligini o’zlashtirishi mumkin, ya’ni voris sinflar umumiy xususiyatlarni vorislik bilan olgan holda, ayrim xususiyatlarni qayta aniqlash orqali yoki yangi xususiyat kiritish orqali tayanch sinfga o’zgartirish mumkin. Shu sababli hosilaviy sinflarni aniqlash sezilarli ravishda kamayadi, chunki unga tayanch sinfdan farqli elementlar qo’shiladi. Aytaylik, bizda alohida shaxsni tavsiflovchi quyidagi Person sinfi mavjud:

```csharp
class Person
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
    public void Display()
    {
        Console.WriteLine(Name);
    }
}
```

Ammo korxona ishchisini tavsiflovchi sinf kerak bo’lib qoldi deylik - bu Employee sinfi. Ushbu sinf Person sinfi bilan bir xil funktsiyani amalga oshirishi sababli, xodim ham o'z navbatida shaxs bo'lganligi sababli, Employee sinfini Person sinfining vorisi (yoki sinf osti) ga aylantirish mantiqan to'g'ri bo'ladi. Bu sinf o’z navbatida ajdod (yoki superklass) tayanch sinf deb nomlanadi:

```csharp
class Employee : Person
{

}
```

Ikki nuqtadan keyin ushbu sinf uchun tayanch sinfni ko'rsatiladi. Person sinfi Employee sinfi uchun tayanch sinf hisoblanadi, va shuning uchun Employee sinfi Person sinfining barcha barcha xususiyatlarni, metodlarni, maydonlarni meros qilib oladi. Meros bo’lib o'tmaydigan yagona narsa bu tayanch sinfning konstruktorlari. Shunday qilib, Vorislik is-a munosabatini amalga oshiradi, Employee sinfining ob'ekti o’z navbatida Person sinfining ham ob'ekti hisoblanadi

```csharp
static void Main(string[] args)
{
    Person p = new Person { Name = "Tom" };
    p.Display();
    p = new Employee { Name = "Sam" };
    p.Display();
    Console.Read();
}
```

Employee sinfining obyekti o’z navbatida Person sinfining ham obyekti bo’lganligi sababli, o'zgaruvchini quyidagicha aniqlay olamiz :

```csharp
Person p = new Employee();
```

Kelishuv bo’yicha, Vorislik oshkor ravishda ko’rsatilmasa ham, barcha sinflar **Object** tayanch sinfining vorisi hisoblanadi. Shuning uchun ham, yuqorida keltirilgan Person hamda Employee sinflari o'zlarining metodlaridan tashqari, Ob'ekt sinfining quyidagi metodlariga ham ega: ToString(), Equals(), GetHashCode() va GetType(). Kelishuv bo'yicha barcha sinflar voris qilib olinishi mumkin. Biroq, bu yerda bir qator cheklovlar mavjud: Person va Employee

* To’plamli vorislik qo'llanilmaydi, sinf faqat bitta sinfdan voris olishi mumkin.
* Hosilaviy sinfni yaratishda tayanch sinfning kirish kaliti ham hisobga olinilishi zarur, yani hosilaviy sinfning kirish kaliti tayanch sinfniki bilan bir xil bo’lishi yoki undanda cheklovliroq bo'lishi talab etiladi. Ya'ni, agar tayanch sinf **internal** kirish kalitiga ega bo'lsa, hosilaviy sinf (voris sinf) ham **internal** yoki **private** kirish kalitiga ega bo’lishi mumkin, lekin **public** kirish kalitiga ega bo’lishi bo’la olmaydi.

  Shuni hisobga olish kerakki, agar tayanch va hosilaviy sinflar har xil loyihalarda bo'lsa, unda hosilaviy sinf faqat public modifikatorga ega bo'lgan sinfdan voris olinishi mumkin.
* Agar sinf **sealed** modifikator bilan e'lon qilingan bo'lsa, u holda ushbu sinfdan voris olib bo’lmaydi. Masalan, quyidagi sinfdan voris olib bo'lmaydi:

  ```csharp
  sealed class Admin
  {
  }
  ```
* Statik sinfdan voris olib bo’lmaydi.


# Overload (Qayta yuklash)

Sobirjonov O'tkirbek

Siz OOP da methodlar bilan ishlayotganingizda sizga **Overloading** va **Overriding** degan so’zlarga duch kelishingiz mumkin. Bu ikki tushuncha odatda methodlar bilan o’z vazifasini amalga oshiradi. **Overloading** va **Overriding** polymorphismni amalga oshirishnining keng tarqalgan usuli hisoblanadi. Biz hozir **Overloading** (Qayta yuklash) haqida batafsil to’xtalib o’tamiz.

### Overloading ishlatilmagandagi holat

Avvaliga bir xato yo’l bilan dastur yozaylik, chunki bu tushunchalar va qayta yuklash amali nimaga kerakligini tushunish uchun avval xato yo’lni ko’ribgina xulosa olishingiz mumkin. Quyidagi dasturda 2-3-4 ta sonlardan eng kattasini topish dasturi yozilgan.

```csharp
using System;  
namespace ConsoleApp1 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            double max1, max2; 
            max1 = GetMaxOf2Numbers(2, 3.3); 
            max2 = GetMaxOf3Numbers(4.7, 3.3, 48.0); 
 
            Console.WriteLine(max1); 
            Console.WriteLine(max2); 
        } 
 
        static double GetMaxOf2Numbers(double number1, double number2) 
        { 
            return (number1 > number2) ? number1 : number2; 
        } 
 
        static double GetMaxOf3Numbers(double number1,  
            double number2, double number3) 
        { 
            if (number1 > number2 && number1 > number3) return number1; 
            else if (number2 > number1 && number2 > number3) return number2; 
            else if (number3 > number2 && number3 > number1) return number3; 
            else return -1; 
        } 
    } 
} 
```

Natija :

```
3.3 
48 
```

Yuqoridagi dasturda ko’rganingizdek

`GetMaxOf2Numbers`

`GetMaxOf3Numbers`

Ushbu methodlar uchun kiruvchi parametrlariga qarab nom berdik, endi yana bir o’ylab ko’ring, agar massiv yoki int toifasidagi sonlar orasidan eng kattasini topish kerak bo’lsachi, quyidagi dasturda buni ham ko’rishingiz mumkin:

```csharp
using System;  
namespace ConsoleApp1 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            double max1, max2, max3; 
             
            max1 = GetMaxOf2Numbers(2, 3.3); 
            max2 = GetMaxOf3Numbers(4.7, 3.3, 48.0); 
 
            double[] arr = new double[] 
            { 
                2, 3.3, 5, 5, 89.0, 112.2, 98, 77 
            }; 
            max3 = GetMaxOfArray(arr); 
 
            Console.WriteLine(max1); 
            Console.WriteLine(max2); 
            Console.WriteLine(max3); 
        } 
 
        static double GetMaxOf2Numbers(double number1, double number2) 
        { 
            return (number1 > number2) ? number1 : number2; 
        } 
 
        static double GetMaxOf3Numbers(double number1,  
            double number2, double number3) 
        { 
            if (number1 > number2 && number1 > number3) return number1; 
            else if (number2 > number1 && number2 > number3) return number2; 
            else if (number3 > number2 && number3 > number1) return number3; 
            else return -1; 
        } 
 
        static double GetMaxOfArray(double[] arr) 
        { 
            if (arr != null) 
            { 
                double max = arr[0]; 
                for(int i=1; i<arr.Length; i++) 
                { 
                    if (arr[i] > max) max = arr[i]; 
                } 
                return max; 
            } 
            else return -1; 
        } 
    } 
}
```

Natija :

```
3.3 
48 
112.2 
```

Yuqorida guvoh bo’lganingizdek nom o’ylab topish va uni ishlatish sizga biroz qiyin bo’lib qolyapti, biz 2-3 ta method uchun nom oson topa olamiz, lekin 200-300 ta methodlar da xatoliklar va chigalliklar yuzaga keladi. Siz yozgan class lardagi methodlar nima amal bajarishini u class ni ishlatayotganda nechta qiymat qabul qiladi, qanday turga mansub bo’lishi kerak hammasini bilib keyingina u methodlardan foydalana olasiz. Buni qanday hal qilish mumkin?

Demak : Biz yuqorida tutgan yo’limiz xato ekanligini tushunib oldik. Siz yozgan kodlarni kompyuter tushunaveradi, lekin o’zingiz va boshqa dasturchilar qiynalib qolishlari mumkin. Endi esa to’g’ri yo’lni o’rganamiz

### Overloading qo’llanilishi

Biz barcha methodlarga bir xil nom berishimiz kerak bo’ladi, qanday turdagi va nechta qiymat kirib kelishidan qat’iy nazar.

```csharp
using System;  
namespace ConsoleApp1 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            double max1, max2, max3; 
             
            max1 = Max(2, 3.3); 
            max2 = Max(4.7, 3.3, 48.0); 
 
            double[] arr = new double[] 
            { 
                2, 3.3, 5, 5, 89.0, 112.2, 98, 77 
            }; 
            max3 = Max(arr); 
 
            Console.WriteLine(max1); 
            Console.WriteLine(max2); 
            Console.WriteLine(max3); 
        } 
 
        static double Max(double number1, double number2) 
        { 
            return (number1 > number2) ? number1 : number2; 
        } 
 
        static double Max(double number1,  
            double number2, double number3) 
        { 
            if (number1 > number2 && number1 > number3) return number1; 
            else if (number2 > number1 && number2 > number3) return number2; 
            else if (number3 > number2 && number3 > number1) return number3; 
            else return -1; 
        } 
 
        static double Max(double[] arr) 
        { 
            if (arr != null) 
            { 
                double max = arr[0]; 
                for(int i=1; i<arr.Length; i++) 
                { 
                    if (arr[i] > max) max = arr[i]; 
                } 
                return max; 
            } 
            else return -1; 
        } 
    } 
 
}
```

Natija :

```
3.3 
48 
112.2 
```

Guvohi bo’lganingizdek hamma method nomini Max ga o’zgartirdik va method **overloading** ni amalga oshirdik. **Overloading** ni qo’llaganimizdan so’ng kodlarimiz qisqaradi va yanada tushunarli bo’ladi, quyidagi dasturda yuqoridagi dasturni qisqargan holati ko’rsatib o’tilgan (Main methodiga e’tibor bering va solishtiring).

```csharp
using System;  
namespace ConsoleApp1 
{ 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            double[] arr = new double[] 
            { 
                2, 3.3, 5, 5, 89.0, 112.2, 98, 77 
            }; 
 
            Console.WriteLine(Max(2, 3.3)); 
            Console.WriteLine(Max(4.7, 3.3, 48.0)); 
            Console.WriteLine(Max(arr)); 
        } 
 
        static double Max(double number1, double number2) 
        { 
            return (number1 > number2) ? number1 : number2; 
        } 
         
        static double Max(double number1,  
            double number2, double number3) 
        { 
            if (number1 > number2 && number1 > number3) return number1; 
            else if (number2 > number1 && number2 > number3) return number2; 
            else if (number3 > number2 && number3 > number1) return number3; 
            else return -1; 
        } 
 
        static double Max(double[] arr) 
        { 
            if (arr != null) 
            { 
                double max = arr[0]; 
                for(int i=1; i<arr.Length; i++) 
                { 
                    if (arr[i] > max) max = arr[i]; 
                } 
                return max; 
            } 
            else return -1; 
        } 
    } 
}
```

Natija :

```
3.3 
48 
112.2 
```

Bu bilan biz nimaga erishdik?

1. Foydalanayotganda turi va nechta qiymat qabul qilishini o’ylab o’tirmasdan, eng kattasini topuvchi method Max ekanmi, demak har qanday turdagi va har qancha qiymat ichidan eng kattasini topib beradi degan fikr paydo bo’ladi , va oson foydalanadi.
2. Siz nom berishda o’ylab o’tirmaysiz, vazifasi bir xil va qabul qiluvchi qiymatlari har xil bo’ladigan holatda method nomini bir nomga keltirib olasiz.
3. Kodlaringiz qisqaradi va yanada tushunarliroq va aniqroq bo’ladi.


# Override (Qayta yozish)

Sobirjonov O'tkirbek

Siz OOP da methodlar bilan ishlayotganingizda sizga **Overloading** va **Overriding** degan so’zlarga duch kelishingiz mumkin. Bu ikki tushuncha odatda methodlar bilan o’z vazifasini amalga oshiradi. Overloading va Overriding polymorphism ni amalga oshirishnining keng tarqalgan usuli hisoblanadi. Biz hozir **Overriding (Qayta yozish)** haqida batafsil to’xtalib o’tamiz.

## Overriding o’zi nima?

Odatda C# da **Overriding** haqida gapirilganda, method **Overriding** nazarda tutiladi. Overriding bizga strukturani o’zgarishsiz ushlab qolgan holda, logikani o’zgartirish imkoniyatini beradi.

## Overriding ishlatilmagandagi holat

Shakllar class larini yaratamiz. Quyidagi kodda inheritance ishlatilgangan holda 3 ta class yaratdik. E’tibor bering hammasida Draw methodi bor.

```csharp
public class Shape 
    { 
 
    } 
 
    public class Circle : Shape 
    { 
        public void Draw() 
        { 
            Console.WriteLine("Aylana chizildi"); 
        } 
    } 
 
    public class Triangle : Shape 
    { 
        public void Draw() 
        { 
            Console.WriteLine("Uchburchak chizildi"); 
        } 
    } 
 
    public class Rectangle : Shape 
    { 
        public void Draw() 
        { 
            Console.WriteLine("To'rtburchak chizildi"); 
        } 
    } 
```

Guvohi bo’lganingizdek “Draw” methodi ko’p bora qo’llanildi. Endi bir o’ylab ko’ring sizda 50 ta shakl classlarini yaratmoqchisiz, har birini chizish, bir biridan boshqacha bo’lsin. 2D va 3D da ham farq qiladi. U class larning har biriga “Draw” methodini e’lon qilib chiqishingiz qanchalar to’g’ri. Ya’ni siz chalkashib Drow yoki Drav deb yozib chalkashishingiz ham mumkin. Yoki birorta classda Draw methodi e’lon qilinmay qolib ketgan bo’lishi ham mumkin. Umumiy qilib aytganda ishonchilik yuqori emas. Bunga qanday yechim topish mumkin.

## Overriding ishlatilgandagi holat

Method overriding ni biz ikki xil usulda ko’rsatib o’tamiz

1. Mavhum (Abstract) classlarni ichida abstract methodlar e’lon qilib, method override amalga oshirish mumkin. Abstract class larni ichida abstract methodlarni e’lon qilasiz va ushbu abstract class dan olingan avlod class o’zida ushbu abstract methodni override qilishi shart bo’lib qoladi.

```csharp
using System;  
namespace ConsoleApp1 
{ 
    public abstract class Shape 
    { 
        public abstract void Draw(); 
    } 
 
    public class Circle : Shape 
    { 
        public override void Draw() 
        { 
            Console.WriteLine("Aylana chizildi"); 
        } 
    } 
 
    public class Triangle : Shape 
    { 
        public override void Draw() 
        { 
            Console.WriteLine("Uchburchak chizildi"); 
        } 
    } 
 
    public class Rectangle : Shape 
    { 
        public override void Draw() 
        { 
            Console.WriteLine("To'rtburchak chizildi"); 
        } 
    } 
 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            Circle circle = new Circle(); 
            circle.Draw(); 
            Triangle triangle = new Triangle(); 
            triangle.Draw(); 
            Rectangle rectangle = new Rectangle(); 
            rectangle.Draw(); 
        } 
    } 
} 
```

Natija :

```
Aylana chizildi 
Uchburchak chizildi 
To'rtburchak chizildi 
```

Yuqoridagi Shape class ga e’tibor bering. Shakl (Shape) - bu mavhum narsa. Ya’ni shakl deganda sizning tasavvuringizda aynan bir shakl tasvirlanmaydi. Uchburchak, Aylana , Romb, To’rtburchak kabi shakllar tasvirlanishi mumkin. Biz kodni tejash va aniqlilikni oshirish uchun, avval Shape class ni abstract holatda yaratib oldik va qolgan classlarni unga avlod class qildik. E’tibor bering! Shape class dagi struktura saqlanib qolyapti, avlod class da Draw nomli method bo’lishi va qayta yozilgan bo’lishini talab qiladi. Bu esa method nomini o’zgarishi e’lon qilinmay qolib ketishi kabi muammolarga yo’l qo’ymaydi.

1. Ixtiyoriy class ichida “virtual” kalit so’zi orqali method override amalga oshirish mumkin. Methodlar oldidan virtual kalit so’zi yozib ketiladi va ushbu virtual e’lon qilingan method tanasi ham yoziladi. Abstract methodlardan farqli o’laroq virtual methodlarda method tanasi ham bo’ladi. Sababi agar biror bir classda ushbu virtual method override qilinmasa, default holatda ushbu ota class dagi virtual method tanasidagi amallar bajariladi.

```csharp
using System; 
namespace ConsoleApp1 
{ 
    public class Shape 
    { 
        public virtual void Draw() 
        { 
            Console.WriteLine("Shakl chizildi"); 
        } 
    } 
 
    public class Circle : Shape 
    { 
        public override void Draw() 
        { 
            Console.WriteLine("Aylana chizildi"); 
        } 
    } 
 
    public class Triangle : Shape 
    { 
        public override void Draw() 
        { 
            Console.WriteLine("Uchburchak chizildi"); 
        } 
    } 
 
    public class Rectangle : Shape 
    { 
    } 
 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            Circle circle = new Circle(); 
            circle.Draw(); 
            Triangle triangle = new Triangle(); 
            triangle.Draw(); 
            Rectangle rectangle = new Rectangle(); 
            rectangle.Draw(); 
        } 
    } 
} 
```

Natija :

```
Aylana chizildi 
Uchburchak chizildi 
Shakl chizildi 
```

E’tibor bering! To’rtburchak ( Rectangle ) class da Draw methodi override qilinmadi. Natijada ota class dagi Draw methodi ishga tushdi va “Shakl chizildi” so’zi yozildi.

Method overriding tushunarli bo’ldi deb o’ylayman. Agar yana kengroq tushunmoqchi bo’lsangiz quyidagi kodni tahlil qiling. Tahlil qilish sizning fikrlashingizni sezilarli darjada oshiradi.

```csharp
using System;  
namespace ConsoleApp1 
{ 
    public abstract class Shape 
    { 
        public virtual void Draw() 
        { 
            Console.WriteLine("Shakl chizildi"); 
        } 
    } 
 
    public class Circle : Shape 
    { 
        private float _radius; 
        public Circle(float radius) 
        { 
            this._radius = radius; 
        } 
        public override void Draw() 
        { 
            Console.WriteLine($"Radiusi {_radius} ga teng bo'lgan aylana chizildi"); 
        } 
    } 
 
    public class Triangle : Shape 
    { 
        private float _a; 
        private float _b; 
        private float _c; 
 
        public Triangle(float a, float b, float c) 
        { 
            _a = a; 
            _b = b; 
            _c = c; 
        } 
 
        public override void Draw() 
        { 
            Console.WriteLine($"Tomonlari {_a} {_b} {_c} ga teng bo'lgan" + 
                $" uchburchak chizildi"); 
        } 
    } 
 
    public class Rectangle : Shape 
    { 
        private float _width; 
        private float _height; 
 
        public Rectangle(float width, float height) 
        { 
            _width = width; 
            _height = height; 
        } 
 
        public override void Draw() 
        { 
            Console.WriteLine($"Tomonlari {_width} {_height} ga teng bo'lgan" + 
                $" to'rtburchak chizildi"); 
        } 
    } 
 
    class Program 
    { 
        static void Main(string[] args) 
        { 
            Circle circle = new Circle(5); 
            circle.Draw(); 
            Triangle triangle = new Triangle(3, 4, 5); 
            triangle.Draw(); 
            Rectangle rectangle = new Rectangle(4, 5); 
            rectangle.Draw(); 
        } 
    } 
} 
```

Natija :

```
Radiusi 5 ga teng bo'lgan aylana chizildi 
Tomonlari 3 4 5 ga teng bo'lgan uchburchak chizildi 
Tomonlari 4 5 ga teng bo'lgan to'rtburchak chizildi 
```

Yuqoridagi dasturlarimizda sezgan bo’lsangiz umumiy struktura o’zgarmadi va logika o’zgardi. Umumiy strukturada, “hamma shaklda Draw methodi bolishi kerak” degan shart bor edi. Lekin Draw methodini tanasini uchburchak, to’rtburchak va boshqa shakl xususiyatlaridan kelib chiqqan xolda o’zgartirishingiz mumkin bo’ldi.


# Base

Xushnazarov Faxriddin

**base** kalit so’zini ishlatishni o’ragtish uchun biz ushbu maqolamizda [Vorislik](https://docs.dot-net.uz/c-.net/basic/essential/vorislik) mavzusida yozgan maqolamizni davom ettiramiz.

```csharp
class Person
{
    public string Name { get; set; }

    public Person(string name)
    {
       Name = name;
    }
    public void Display()
    {
       Console.WriteLine(Name);
    }
 }
 class Employee : Person
 {
    public string Company { get; set; }
    public Employee(string name, string company)
         : base(name)
    {
        Company = company;
    }
}
```

Person sinfi Name xususiyatini o'rnatadigan konstruktorga ega. Employee sinfi Name xususiyatini voris qilib olganligi va o'rnatganligi sababli, o'rnatish kodini qayta qayta yozmasdan qandaydir tarzda Person sinfining tegishli kodini yozish mantiqan to'g'ri bo'ladi. Bundan tashqari, tayanch sinf konstruktorida o'rnatilishi kerak bo'lgan yana bir qancha xususiyatlar va parametrlar bo'lishi mumkin. **base** kalit so’zi yordamida biz tayanch sinfga murojaat qilishimiz mumkin. Bizning holatimizda "Employee" sinfining konstruktorida ism va kompaniyani belgilashimiz kerak. Ammo biz o'rnatish uchun ismni tayanch sinfning konstruktoriga, ya'ni Person sinfining konstruktoriga base(name) ifodasi yordamida uzatamiz.

```csharp
static void Main(string[] args)
{
    Person p = new Person("Bill");
    p.Display();
    Employee emp = new Employee("Tom", "Microsoft");
    emp.Display();
    Console.Read();
}
```

Konstruktorlar voris olayotganda voris sinfga o'tmaydi. Va agar tayanch sinfda kelishuv bo'yicha parametrsiz konstruktor aniqlanmagan, faqat parametrlarga ega bo'lgan konstruktorlar aniqlangan (Person bazaviy sinfda bo'lgani kabi) bo’lsa, u holda hosilaviy sinfda biz ushbu konstruktorlardan birini base kalit so'z yordamida chaqirishimiz kerak. Masalan, Employee sinfidan konstruktorni olib tashlimiz:

```csharp
class Employee : Person
{
    public string Company { get; set; }
}
```

Bu holda xatolik yuz beradi, chunki "Employee" sinfi "Person" sinfiga to'g'ri kelmaydi, ya'ni u tayanch sinfning konstruktorini chaqirmaydi. Agar bir xil xususiyatlarni o'rnatadigan biron bir konstruktorni qo'shsak ham, xatolik yuz beradi:

```csharp
public Employee(string name, string company)
{
    Name = name;
    Company = company;
}
```

Ya'ni, Employee sinfida **base** kalit so'z orqali Person sinfining konstruktori oshkor ravishda chaqirilishi kerak:

```csharp
public Employee(string name, string company): base(name)
{
Company = company;
}
```


# Polimorfizm

Ravshan Sodiqov

Navbatdagi darsimiz ob’ektga yo’naltirilgan dasturlashning yana bir asosiy tushunchalaridan biri polimorfizm haqida. Polimorfizm odatda inkapsulyatsiya va vorislikdan keyin OOP ning uchinchi ustuni deyiladi. *Polimorfizm* yunoncha so’z bo’lib, “ko’p shaklli” degan ma’noni anglatadi va uning ikki xil ko’rinishi mavjud:

1. **Statik polimorfizm**. Ushbu tur *kompilyatsiya vaqti polimorfizmi (Compile Time Polymorphism)* deb ham yuritiladi. Chunki u qaysi metod yoki funksiyani chaqirishni kompilyatsiya vaqtida aniqlashtirib oladi va mos keladigan metod yoki funksiya topilmasa xatolik qaytariladi.

Quyida “Algebra” sinfida bir xil nomga ega ikkita “Add” metodi mavjud va bu metodlar faqat parametrlari bilan farqlangan. 1 – “Add” metodining vazifasi 2 ta butun sonni qabul qilib, ularning yig’indisini qaytarish. 2 – “Add” metodining vazifasi 3 ta butun sonni qabul qilib, ularning yig’indisini qaytarish.

```csharp
class Algebra
{
  public int Add(int a, int b)
  {
    return a + b;
  }
  public int Add(int a, int b, int c)
  {
    return a + b + c;
  }
}
```

Keling endi dastur qanday ishlashini yaxshiroq tushunish uchun, “Algebra” sinfining “Add” metodidan ikki xil ko’rinishidan ham foydalanib ko’ramiz:

```csharp
class Algebra
    {
        public int Add(int a, int b)
        {
            return a + b;
        }

        public int Add(int a, int b, int c)
        {
            return a + b + c;
        }
    }
    
    class Program
    {   
        static void Main(string[] args)
        {
            Algebra algebra = new Algebra();
            Console.WriteLine(algebra.Add(3, 8)); //output: 11
            Console.WriteLine(algebra.Add(2, 3, 8)); //output: 13
            Console.ReadKey();
        }    
    }
```

Biz sinf metodiga algebra.Add(3, 8) shaklida murojaat qildik va kompilyastiya jarayoni boshlangandan keyin dastur ikkita parametrli metodga ya’ni 1 – “Add” metodiga murojaat qildi. (Mustaqil tarzda s.Add(2, 3, 5) holatini o’rganib chiqing). Biz statik polimorfizmda bir metodni sinfni o’zida qayta aniqladik va qaysi metod ishlashi kerak ekanligi kompilyatsiya vaqtida aniq bo’ldi.

1. **Dinamik polimorfizm**. Runtime polimorfizmi yoki kech ulanish polimorfizmi deb ham atash mumkin. Polimorfizmning ushbu turida statik polimorfizmdan farqli tarzda bir sinfga tegishli metodlarni ushbu sinfdan voris oluvchi boshqa sinflarda qayta aniqlaymiz. Bu nima degani ? Misol tariqasida real bir voqeani qaraymiz. Geometrik shakl deganimizda uchuburchak, to’rtburchak, piramida va yana boshqa shakllar ko’z oldimizdan o’tadi. Lekin aynan bir shaklni tasavvur qila olmaymiz. Uchburchak deganimizda esa aksincha. Ushbu holat quyidagicha:

```csharp
class Shakl
    {
        public void Chizish()
        {
            Console.WriteLine("Men shakl chizaman");
        }
    }

    class Uchburchak : Shakl
    {
        public void Chizish()
        {
            Console.WriteLine("Men uchburchak chizaman");
        }
    }

    class Aylana : Shakl
    {
        public void Chizish()
        {
            Console.WriteLine("Men aylana chizaman");
        }
    }
```

Yuqoridagi holatda “Shakl” sinfi ajdod sinf va unda Chizish() metodi mavjud, “Aylana” va “Uchburchak” sinflari esa uning voris sinflari va Chizish() metodini esa ularda qayta yozdik.

```csharp
    class Shakl
    {
        public void Chizish()
        {
            Console.WriteLine("Men shakl chizaman");
        }
    }

    class Uchburchak : Shakl
    {
        public void Chizish()
        {
            Console.WriteLine("Men uchburchak chizaman");
        }
    }

    class Aylana : Shakl
    {
        public void Chizish()
        {
            Console.WriteLine("Men aylana chizaman");
        }
    }

    class Program
    {   
        static void Main(string[] args)
        {
            //konstruktorlar e'loni
            Shakl shakl = new Shakl();
            Shakl uchburchak = new Uchburchak();
            Shakl aylana = new Aylana();

            //Metodni chaqirish
            shakl.Chizish();
            uchburchak.Chizish();
            aylana.Chizish();

            Console.ReadKey();
        }    
    }
```

Natija qanday bo’ladi ?

![Natija](https://user-images.githubusercontent.com/91861166/147952367-3db0cf1b-190f-4f8a-ac65-d0f81500296f.png)

Nega natija biz o’ylagandek chiqmadi ? Biz yuqorida ikkita xatoga yo’l qo’ydik.

**1 – xato:** Chizish() metodini ajdod sinfda, ya’ni, Shakl sinfida qayta yozish imkoniyati bor ekanligini aytmadik. (virtual so’zi bilan hal qilamiz)

**2 – xato :** Chizish() metodini voris sinflarda qayta yozayotganimizni ham aytib o’tmadik. (override so’zi bilan hal qilamiz)

Dasturga muammolarimizni hal qiluvchi kalit so’zlarni qo’shamiz:

```csharp
namespace PolymorphismDemoApp
{
    class Shakl
    {
        public virtual void Chizish()
        {
            Console.WriteLine("Men shakl chizaman");
        }
    }

    class Uchburchak : Shakl
    {
        public override void Chizish()
        {
            Console.WriteLine("Men uchburchak chizaman");
        }
    }

    class Aylana : Shakl
    {
        public override void Chizish()
        {
            Console.WriteLine("Men aylana chizaman");
        }
    }

    class Program
    {   
        static void Main(string[] args)
        {
            //konstruktorlar e'loni
            Shakl shakl = new Shakl();
            Shakl uchburchak = new Uchburchak();
            Shakl aylana = new Aylana();

            //Metodni chaqirish
            shakl.Chizish();
            uchburchak.Chizish();
            aylana.Chizish();

            Console.ReadKey();
        }    
    }
}
```

Xatolarimizni hal qila oldikmi ?

![Natija](https://user-images.githubusercontent.com/91861166/147952466-5b1185c3-4d90-4517-98f0-56a12420189a.png)

Xayriyat, endi natija biz xohlagan ko’rinishda !

### Abstraksiya olamiga sayohat

Yuqorida biz geometrik shakl deganda aynan bir shakl ko’z oldimizga kelishini va uni chizish mumkin emasligini tushunib yetdik. Demak, “Shakl” sinfi mavhum (abstract) sinf va uning “Chizish” metodi ham mavhum (abstract). Voris sinflarda esa bu metodning qiladigan ishi tayin.

```csharp
namespace PolymorphismDemoApp
{
    abstract class Shakl
    {
        public abstract void Chizish();
    }

    class Uchburchak : Shakl
    {
        public override void Chizish()
        {
            Console.WriteLine("Uchburchak chizaman");
        }
    }

    class Aylana : Shakl
    {
        public override void Chizish()
        {
            Console.WriteLine("Aylana chizaman");
        }
    }

    class Program
    {   
        static void Main(string[] args)
        {
            //konstruktorlar e'loni
            //Shakl shakl = new Shakl(); endi Shakl sinfining kostruktrini yaratib bo'lmaydi 
            Shakl uchburchak = new Uchburchak();
            Shakl aylana = new Aylana();

            //Metodni chaqirish
            uchburchak.Chizish();
            aylana.Chizish();

            Console.ReadKey();
        }    
    }
}
```

{% hint style="info" %}
OOP ni amalda yaxshi qo’llashni istasangiz quyidagi 3 qoidani doimo yodda tuting:

**1 – qoida:** Abstract metodlarni yaratishda metod nomi oldiga abstract so’zini qo’shish kerak va abstract metodlarning tanasi bo’lmaydi.\
**2 – qoida:** Hech bo’lmaganda bitta bo’lsa ham abstract metodni o’z ichiga olgan sinf o’z – o’zidan abstract sinfga aylanadi va sinf nomi oldiga abstract so’zi qo’shib qo’yiladi.\
**3 – qoida:** Abstract sinflar umumiylikni saqlab turish uchun yaratiladi va ularning kostruktori e’loni ham mavjud bo’lmaydi.
{% endhint %}

Yuqoridagi dasturda hayotdagi haqiqiy voqeani aks ettirdik deyishimiz mumkin. “Shakl” sinfi mavhum (abstract) va “Aylana”, “Uchburchak” sinflari uchun ajdod sinf. Undagi Chizish() metodi ham hech qanday vazifa bajarmasdan faqat umumiylikni saqlab turish uchun yaratildi va voris sinflarda ushbu metodni qayta aniqladik (override kalit so’zi orqali).

Yakunda yana bir muhim qoidani bilishingizni ta’kidlab, shu bilan mavzuni o’z nihoyasiga yetkazamiz:

{% hint style="info" %}
**Yodda tuting:** Agar ajdod sinfdagi metod *virtual* bo’lsa, bu sinfdan voris olganimizda bu metodni qayta aniqlashimiz majburiy emas, ya’ni agar ehtiyoj bo’lsagina qayta aniqlaymiz. Agar ajdod sinfdagi metod *abstract* bo’lsa bu sinfdan voris olganimizda bu metodni qayta aniqlashga majburmiz.
{% endhint %}


# Sealed

Niyozbek Mirzayev

C# dasturlash tilida **Sealed class** tushunchasi mavjud.

{% hint style="info" %}
**Sealed class** deb o'zidan voris (inheritance) qoldirmaydigan classlarga aytiladi. Sealed class yaratish uchun C# dasturlash tilida class yozuvidan oldin **sealed** kalit so'zini yozish lozim. Sealed kalit so'zi kompilyator uchun bu classdan voris olib bo'lmasligini bildiradi.
{% endhint %}

Sealed classga misol:

```csharp
	sealed class class_nomi
	{
	    // xususiylatlar
	    // methodlar
	
	}
```

Quyidagi kodda sealed classdan voris olishga harakat qilingan:

```csharp
namespace Sealed_Class
{
	internal class Program
	{
		static void Main(string[] args)
		{
			//....
		}

		// sealed classni yaratish
		public sealed class Class_nomi1
		{
			//....
		}

		//seled klassdan voris olishga harakat qilish
		public class Class_nomi2 : Class_nomi1
    		{
			//...
		}
	}
}
```

Agar kod ishga tushirilsa natija quyidagicha bo'ladi:

```
💡 error CS0509: 'Class_nomi2': cannot derive from sealed type 'Class_nomi1'
```

{% hint style="info" %}
Methodlar ham sealed bo'lishi mumkin, lekin sealed qilingan methodning classi, biror-bir classning vorisi bo'lishi lozim. Methodni sealed qilinishidan asosiy maqsad: voris classdagi methodni override qilishdan himoya qilish.
{% endhint %}

(Override yoki shu kabi tamoyillar haqida bilmasangiz, oldingi maqolalarni ko'rishingiz mumkin.)

Tushunishga qiyin bo'lishi mumkin, ammo quyidagi kodda tushunish osonroq:

```csharp
namespace Sealed_Class
{
	internal class Program
	{

		static void Main(string[] args)
		{
			//....
		}

		public class Asosiy
		{
			// voris bo'ladigan method
			 public virtual int Add(int a, int b)
			 {
				  return a + b;
			 }
		}

		//asosiy classdan voris olish
		public class Voris1 : Asosiy
    		{
			//voris bo'lgan methodni sealed qilish
			public sealed override int Add(int a, int b)
			{
				return a + b;
			}
		}
	}
}
```

Yuqoridagi kodda voris bo'lgan method polymorphism yordamida sealed qilindi, yani Voris1 classidagi Add methodini boshqa classda voris olib bo'lmasligi ta'minlandi.

Quyidagi kodda, esa yuqoridagi kodning sealed qilingan methodidan voris olishga harakat qilingan:

```csharp
namespace Sealed_Class
{
	internal class Program
	{	
		static void Main(string[] args)
		{
			//....
		}

		public class Asosiy
		{
			// voris bo'ladigan method
			 public virtual int Add(int a, int b)
			 {
				  return a + b;
			 }
		}

		//asosiy classdan voris olish
		public class Voris1 : Asosiy
		{
			//voris bo'lgan methodni sealed qilish
			public sealed override int Add(int a, int b)
			{
				return a + b;
			}
		}
		
		public class Voris2 : Voris1
		{
			//sealed bo'lgan methoddan voris olishga urinish
			public override int Add(int a, int b)
			{
				return a + b;
			}
		}
	}
}
```

Natija quydagicha bo'ladi:

```
💡 error CS0239: 'Program.Voris2.Add(int, int)': cannot override inherited member 'Program.Voris1.Add(int, int)' because it is sealed.
```


# Interface

Sobirjonov O'tkirbek

## Interface o’zi nima?

**Interfeys (en, Interface)** - bu aloqador bo'lmagan obyektlar orasida o'zaro ta'sir qilish uchun foydalanadigan qurilma yoki tizim.\
Masalan : Masofadan boshqarish pulti - siz va televizor o'rtasidagi interfeys. Ingliz tili - ikki kishi o'rtasidagi interfeys. Interface qanday yaratiladi? Interface larni yaratish juda ham oson. Quyidagi ko’rinishda interface yaratishingiz mumkin.

```csharp
public interface IAnimal 
    { 
        public void Run(); 
        public void Jump(); 
        public void Eat(); 
    } 
```

Interface larni yaratishda bir qoida bor, Masalan siz Animal interface ni yaratmoqchi bo’lsangiz IAnimal deb nomlashingiz kerak, yoki Person interface ni yaratmoqchi bo’lsangiz IPerson deb nomlar ketishingiz kerak. Nomlar oldidan kelgan “I” harfi bu interface ekanligini bildirib turadi. Interface larda faqat funksiya prototipi e’lon qilib ketiladi va funksiya tanasi yozilmaydi. Ya’ni logika yozilmaydi, logikani siz ushbu interface ni implimentatsiya qilgan class da yozasiz. Bu sizga ma’lum bir obyekt xususiyatlarini ajratib olishingizda juda katta yordam beradi.\
Interface ni biror class implementation (implimentatsiya) qilishi mumkin. Va ushbu interface dagi xususiyatlarini o’ziga biriktirib oladi.

```csharp
public interface IAnimal 
    { 
        public void Run(); 
        public void Jump(); 
        public void Eat(); 
    } 
 
    public class Animal : IAnimal 
    { 
        public void Eat() 
        { 
            Console.WriteLine("Oziqlandi"); 
        } 
 
        public void Jump() 
        { 
            Console.WriteLine("Sakradi"); 
        } 
 
        public void Run() 
        { 
            Console.WriteLine("Yugurdi"); 
        } 
    } 
```

Biror bir class, interfacedan me’ros olgan bo’lsa interface dagi barcha funksiyalarni o’zida e’lon qilishi shart bo’ladi. Masalan : Run yoki Jump funksiyalari e’lon qilinmay qolib ketsa xatolik yuz beradi. Buning afzalligi Interface da funksiya tanasi bo’lmaganligi uchun, umumiy strukturani o’zida saqlab turadi. Haqiqiy proyektlarda juda ko’p interface lar va juda ko’p methodlar bo’ladi, va ular orasidan biror bir method yozilmay qolishi ehtimoli bo’ladi va shunda interface ni qaysi methodi e’lon qilinmaganligi haqidagi error paydo bo’ladi.

## Multiple Inheritance

**Multiple Inheritance** bir yoki bir nechta classlardan meros olish degan ma’noda qo’llaniladi. Quyidagi class lar meros olish strukturasiga e’tibor bering.

```csharp
   public class Father 
    { 
    } 
    public class Mother 
    { 
    } 
 
    public class Child : Father, Mother 
    { 
    } 
```

Ushbu ko’rinishda meros olish , ya’ni child class ham father ham mother class laridan meros olish xususiyati C++ va boshqa ko’p tillarda qo’llab quvvatlanadi. Lekin C# da esa bunga ruxsat yo’q. Child class, Father class ga voris bo’lishi yoki Mother class ga voris bo’lishi mumkin xolos. Quyidagi ko’rinishda

```csharp
public class Father 
    { 
    } 
    public class Mother 
    { 
    } 
 
    public class Child : Father 
    { 
    } 
```

Yoki

```csharp
    public class Father 
    { 
    } 
    public class Mother 
    { 
    } 
 
    public class Child : Mother 
    { 
    }  
```

## Interfaceni Multiple Inheritance ga nima aloqasi bor?

**Interface**lar **multiple inheritance** ni qo’llab quvvatlaydi. **Multiple Inheriatance** - **Interface**larni larni qo’llashdagi asosiy imkoniyatlardan biri hisoblanadi. Ya’ni bir class bir nechta interface lardan meros olishi mumkin. Bir dastur yozsakda, u orqali interface larni ishlatishni samarasi va multiple inheritance ga nima aloqasi bor ekanligi tushunib olsak. Tasavvur qiling, biz hayvonlar classini tuzish jarayonidamiz va ularning xususiyatlarini belgilayapmiz.

```csharp
public interface IRunnable 
    { 
        public void Run(); 
    } 
    public interface IJumpable 
    {
        public void Jump(); 
    } 
    public interface ISwimmable 
    { 
        public void Swim(); 
    } 
    public interface IHuntable 
    { 
        public void Hunt(); 
    } 
```

## Interface larni yaratib oldik, endi esa ularni qo’llashimizga e’tibor bering

```csharp
public class Fish : ISwimmable 
    { 
        public void Swim() 
        { 
            Console.WriteLine("Suzdi"); 
        } 
    } 
 
    public class Tiger : IRunnable, ISwimmable,  
        IJumpable, IHuntable 
    { 
        public void Hunt() 
        { 
            Console.WriteLine("Ov qildi"); 
        } 
 
        public void Jump() 
        { 
            Console.WriteLine("Sakradi"); 
        } 
 
        public void Run() 
        { 
            Console.WriteLine("Yugurdi"); 
        } 
 
        public void Swim() 
        { 
            Console.WriteLine("Suzdi"); 
        } 
    } 
 
    public class Deer : IRunnable, IJumpable, ISwimmable 
    { 
        public void Jump() 
        { 
            Console.WriteLine("Sakradi"); 
        } 
 
        public void Run() 
        { 
            Console.WriteLine("Yugurdi"); 
        } 
 
        public void Swim() 
        { 
            Console.WriteLine("Suzdi"); 
        } 
    }  
```

Classlarni ham yaratib oldik, endi ularni tahlil qilsak:

1. Fish (Baliq) class: Suza oladi Ov qilolmaydi Yugura olmaydi Sakray olmaydi
2. Tiger (Yo’lbars) class : Suza oladi Ov qiladi Yugura oladi Sakray oladi
3. Deer (Kiyik) class: Suza oladi Ov qilmaydi Yugura oladi Sakray oladi

## Interfacelar nima uchun kerak?

1. Interface lar Multiple Inheritance ni qo’llab quvvatlaydi.
2. Interface lar asosiy strukturani ushlab turadi.
3. Interface lar kodni qisqarishi , tushunarli bo’lishi va umumiylashgan bo’lishiga yordam beradi.
4. Interface lar dastur tezroq yozilishiga yordam beradi ( Avval Interface larni yozib chiqsangiz, dasturingiz nima qilishini yozgan bo’lasiz, va ularni classlarda implementatsiya qilib, dasturingiz u amallarni qanday amalga oshirishini yozasiz)
5. Interface lar Dependency Injection uchun juda katta yordam beradi. SOLID ning “D” (Dependency Enviroment ) tamoyiliga amal qilishingizda asosan interfacelar ishlaydi. (Agar bu afzallikda siz tushunmagan narsalar bo’lsa e’tibor bermang, ularni keyingi mavzularda o’rganib olasiz).

Demak barchasi tushunarli bo’ldi degan umiddaman, agar tushunmagan bo’lsangiz qayta qayta o’qib chiqing va dasturlaringizda ishlatib ko’ring.


# Modifikatorlarga ruxsat berish

Buzurgmexr Sultonaliyev

### Ruxsat modifikatorlari

**Ruxsat modifikatorlari** - class, record, struct, interface va uning a'zolari, enum-ga qo'shiladigan kalit so'zlar bo'lib, ularning ko'rinishini va asosan ulardan qayerda foydalanish mumkinligini belgilaydi. Ushbu kalit so'zlar bizga inkapsulyatsiyani saqlashga va tasodifiy o'zgarishlarning oldini olishga yordam beradi, shu bilan kodimizni toza va xavfsiz saqlaydi.

### Ahamiyati

Ruxsat modifikatorlaridan strategik foydalanish quyidagi sabablarga ko'ra C# da juda muhim:

* Bu yaxshi tuzilgan kodni ta'minlab, inkapsulyatsiya tamoyillariga rioya qilishga yordam beradi.
* Bu obyektning ichki holatini qasddan o'zgartirishning oldini oladi.
* U ilovaning turli qatlamlari o'rtasida qanday foydalanishni belgilab beradi.

Shunday qilib, ruxsat modifikatorlarining kuchidan foydalanishga tayyormisiz? Keling, har xil turlarni ko'rib chiqaylik!

### Turlari

C# har biri o'ziga xos funksionallikka ega bo'lgan oltita ruxsat modifikatorini taklif qiladi. Keling bularga kirishdan oldin *solution* va *csproj* degan tushunchalarga oydinlik kiritsak.

* **solution** - Visual Studio-da dastur yaratishda yoki boshqa C# loyihasini boshlashda ishlatiladi. Solution, bir yoki bir nechta proyektlarni birlashtiradi. Agar sizning loyihangizda bir nechta proyektlar (masalan, web ilovalar, desktop ilovalar, test proyektlar...) bo'lsa, ularni bir-biriga bog'lash va bir bosh sahifa orqali barchasiga nazorat qilish uchun solution yaratishimiz mumkin.
* **csproj** - har bir C# proyekti, u tilda joylashgan direktoriyada joylashgan, proyektning asosiy fayli csproj fayli orqali nazorat qilinadi. Bu faylda proyektning qanday ma'lumotlarni, qaysi fayllarni, klasslarni, boshqa proyektlar bilan bog'lanishni, ilova versiyasini va ko'p boshqa sozlamalarni o'z ichiga olgan. Csproj fayli, proyekt yaratish, tarqatish va ishga tushirish jarayonlarini boshqarish uchun ishlatiladi.

Agar siz bitta loyihadagi bir nechta proyektlarni birlashtirishni xohlasangiz, siz barchasini o'z ichiga oladigan bir solution fayli yaratishingiz mumkin. Solution fayli sizning barcha proyektlaringizni boshqarish, ular orasida aylanish va ularga qo'shimcha sozlamalar qo'shish imkoniyatini beradi.

Masalan, bir loyihaning tuzilishi quyidagicha ko'rinadi:

```
MySolution/
  ├── MyConsoleApp/
  │     ├── Program.cs
  │     └── MyConsoleApp.csproj
  ├── MyLibrary/
  │     ├── MyClass.cs
  │     └── MyLibrary.csproj
  └── MySolution.sln
```

Bu yerda **MySolution.sln** - bu solution fayli, **MyConsoleApp.csproj** va **MyLibrary.csproj** - bu esa proyektlarning csproj fayllari.

![](/files/lZU5WsMPgXAAHcPIDNWS)

#### public

**public** (umumiy ruxsat modifikatori) - bu kalit so'z orqali yaratilgan class, record, struct, interface va uning a'zolarini butun *solution* bo'yicha ishlatishga ruxsat beradi. Ya'ni biz solution ichidagi hamma proyektlarda ishlatish imkoniga ega bo'lamiz

```csharp
public class Hayvon
{
  public string Nom; // Umumiy ruxsat modifikatori ishlatilgan.

  public void Gapir()
  {
    Console.WriteLine("Salom, mening ismim " + Nom);
  }
}

class Program
{
  static void Main(string[] args)
  {
    Hayvon meningHayvonim = new Hayvon();

    // "Nom" umumiy a'zosiga shu yerdan kirishingiz mumkin.
    meningHayvonim.Nom = "Oybola";
    meningHayvonim.Gapir(); // Chiqish: Salom, mening ismim Oybola
  }
}
```

#### internal

**internal** (ichki ruxsat modifikatori) - bu kalit so'z orqali yaratilgan class, record, struct, interface va uning a'zolarini butun proyekt bo'yicha ishlatishimiz mumkin bo'ladi. *Solution* dagi boshqa proyektlarda foydalana olmaymiz.

Keling bitta *BirinchiDastur* degan proyekt yaratamiz va unda bitta sinf yaratamiz:

```csharp
namespace BirinchiDastur;

public class Nuqta
{
  internal int x;
  internal int y;

  public Nuqta Namuna()
  {
    Nuqta p = new Nuqta();
    return p;
  }
}

```

Yuqorida `Nuqta` nomli sinf yaratdik. Uning `x` va `y` degan xususiyatlariga `internal` ruxsat modifikatori berilgan. Va `Namuna` nomli metod yaratdik. Bu metod bizga shu sinfdan namuna olib qaytaradi.

Ana endi shu yaratgan sinfimizni boshqa proyektdan turib ishlatmoqchi bo'lsak quyidagicha ko'rinishda bo'ladi:

```csharp
using BirinchiDastur;

class BoshqaDastur
{
  static void Main()
  {
    Nuqta nuqta = new Nuqta();
    nuqta.Namuna();

    //Console.WriteLine(nuqta.x); // Kompilyatsiya vaqtida xato
    // "Nuqta.x" ga himoya darajasi tufayli kirish imkonsiz
  }
}
```

Ya'ni, Nuqta sinfining `x` va `y` xususiyatlari `internal` bo'lganligi uchun ham uni boshqa proyektda ishlatishga ruxsat yo'q. Lekin Nuqta sinfining `Namuna` nomli metodi public bo'lganligi uchun bemalol ishlatish imkoniyatiga egamiz.

#### protected

**protected** (himoyalangan ruxsat modifikatori) - bu kalit so'z orqali yaratilgan class (yoki record) a'zolarini shu class(yoki record) dan voris olingan class (yoki record) ichidagina foydalanishimiz mumkin.

```csharp
class Hayvon
{
  protected string tovush; // Himoyalangan ruxsat modifikatori ishlatilgan.

  public Hayvon(string hayvonTovushi)
  {
    tovush = hayvonTovushi;
  }
}

class It : Hayvon
{
  public It(string itTovushi) : base(itTovushi) { }

  public void Vovilla()
  {
    Console.WriteLine("It deydi " + tovush); // Biz ushbu olingan sinfdagi himoyalangan a'zo "tovush" ga kira olamiz.
  }
}

class Program
{
  static void Main(string[] args)
  {
    It meningItim = new It("Vav!");
    meningItim.Vovilla(); // Chiqish: It deydi Vav!
  }
}
```

#### private

**private** (shaxsiy ruxsat modifikatori) - bu kalit so'z orqali yaratilgan class, record, struct va uning a'zolarini faqat shu class, record, struct-ning ichidagina foydalanish huquqini beradi. (Interface a'zolari uchun bu ruxsat modifikatorini qo'llay olmaymiz.)

```csharp
class Hayvon
{
  private int yosh; // Shaxsiy ruxsat modifikatori ishlatilgan.

  public void YoshniOrnat(int yangiYosh)
  {
    yosh = yangiYosh;
  }

  public int YoshniOl()
  {
    return yosh;
  }
}

class Program
{
  static void Main(string[] args)
  {
    Hayvon meningHayvonim = new Hayvon();

    // Siz to'g'ridan-to'g'ri boshqa sinfdan "age" shaxsiy a'zosiga kira olmaysiz.
    // myAnimal.age = 4; // Bu kompilyatsiya vaqtida xatolikka olib keladi.

    // Buning o'rniga, shaxsiy a'zolarga kirish uchun umumiy ruxsat etilgan metodlardan foydalanishingiz kerak.
    meningHayvonim.YoshniOrnat(4);
    Console.WriteLine("Yosh: " + meningHayvonim.YoshniOl()); // Chiqish: Yosh: 4
  }
}
```

#### protected internal

**protected internal** (himoyalangan ichki ruxsat modifikatori) - bu kalit so'z orqali yaratilgan class, record, interface va ularning a'zolarini shu va boshqa proyektda shu class, record yoki interface dan voris olgandagina ishlatish imkonini beradi.

Keling yuqorida yaratgan *Nuqta* nomli sinfimizga o'zgartirish kiritsak:

```csharp
namespace BirinchiDastur;

public class Nuqta
{
  protected internal int x;
  protected internal int y;

  public Nuqta Namuna()
  {
    Nuqta p = new Nuqta();
    return p;
  }
}

```

Yuqorida `x` va `y` nomli xususiyatlarimizga `protected internal` ruxsat modifikatorini berdik.

Uni *BoshqaDastur* nomli proyektimizda quyidagicha ishlatishimiz mumkin:

```csharp
using BirinchiDastur;

class BoshqaDastur: Nuqta
{
  static void Main()
  {
    Nuqta nuqta = new Nuqta();
    nuqta.Namuna();

    //Console.WriteLine(nuqta.x); // Kompilyatsiya vaqtida xato
    // "Nuqta.x" ga himoya darajasi tufayli kirish imkonsiz

    BoshqaDastur boshqaDastur = new BoshqaDastur();
    boshqaDastur.Namuna();

    Console.WriteLine(boshqaDastur.x);
    Console.WriteLine(boshqaDastur.y);
  }
}
```

Ya'ni, Nuqta sinfining `x` va `y` xususiyatlari `protected internal` bo'lganligi uchun ham uni boshqa proyektda to'ridan-to'g'ri ishlata olmaymiz. Kompilyatsiya vaqtida xatolik qaytaradi. Lekin Nuqta nomli sinfimizdan voris oladigan bo'lsak va uning vorisidan namuna olsak, `protected internal` ruxsat modifikatori ana o'sha namunada `x` va `y` nomli xususiyatlarimizni ishlatishga imkon beradi.

#### private protected

**private protected** (himoyalangan shaxsiy ruxsat modifikatori) - bu kalit so'z orqali yaratilgan class, record, interface va ularning a'zolarini shu proyektda, shu class, record, interface-dan voris olgandagina ishlatish imkonini beradi.

Bunda *Nuqta* nomli sinfimiz quyidagi holatga keladi:

```csharp
namespace BirinchiDastur;

public class Nuqta
{
  private protected int x;
  private protected int y;

  public Nuqta Namuna()
  {
    Nuqta p = new Nuqta();
    return p;
  }
}

class TogriChiziq: Nuqta
{ 
  public TogriChiziq(int x, int y)
  {
    this.x = x;
    this.y = y;
  }
}
```

Yuqorida *Nuqta* nomli sinf joylashgan proyektda *‌TogriChiziq* nomli yangi sinf yaratdik va *Nuqta* sinfidan voris oldik. Shu holatda *Nuqta* sinfining `x` va `y` xususiyatlaridan foydalanishimiz mumkin bo'ladi

Ana endi shu yaratgan sinfimizni boshqa proyektdan turib ishlatmoqchi bo'lsak quyidagicha ko'rinishda bo'ladi:

```csharp
class BoshqaDastur : Nuqta
{
  static void Main()
  {
    Nuqta nuqta = new Nuqta();
    nuqta.Namuna();

    //Console.WriteLine(nuqta.x); // "Nuqta.x" ga himoya darajasi tufayli kirish imkonsiz

    BoshqaDastur boshqaDastur = new BoshqaDastur();
    boshqaDastur.Namuna();

    //Console.WriteLine(boshqaDastur.x); // "Nuqta.x" ga himoya darajasi tufayli kirish imkonsiz
    //Console.WriteLine(boshqaDastur.y); // "Nuqta.x" ga himoya darajasi tufayli kirish imkonsiz
  }
}
```

Ya'ni, Nuqta sinfining `x` va `y` xususiyatlari `private protected` bo'lganligi uchun ham uni boshqa proyektda ishlatishga ruxsat yo'q.

### Standart ruxsat modifikatori

Agar biz enum va class, record, struct, interface va ularning a'zolariga hech qanday ruxsat modifikatorlarini qo'llamasak, ular avvalboshdan o'rnatilgan ruxsat modifikatorlarini qabul qiladi. Ular quyidagi jadvalda aks ettirilgan:

![](/files/UjvLYJFJqmZgeUeiVofc)


# Inkapsulatsiya

(AlJavhar) Javohirbek Boyaliyev

"Inkapsulyatsiya" so'zi lotincha "in capsula" - qobiqda joylashtirish so'zidan olingan. Shundan kelib chiqib inkapsulatsiyani izolyatsiyalash, atrof muhit ta'siridan himoya qilgan holda yopish, himoyalash, biror bir buyum, narsani qolib, kapsulaga solib qo'yish deb tushunish mumkin.

![](https://user-images.githubusercontent.com/91861166/212597878-c7ed3fd7-5a4e-4436-9da4-64983745bb9d.png)

Bu terminni saaaal dasturlashga bog'lab jaydaricha tushuntiradigan bo'lsak, o'zi inkapsulyatsiya dasturchilar o'z code larini boshqa dasturchilar tomonidan hurmat qilinishi va muhim qismlarini bilmasdan KATTA BUG gacha olib keladigan qilib o'zgartirib yubormasliklari uchun o'ylab topilgan QUROL!!!

![](https://user-images.githubusercontent.com/91861166/212598146-3da30f17-2f6d-47d7-a153-14ee396e88e4.png)

Endi ozmuncha bu masalaga ilmiy yondashamiz va bunga doir code ni ko'rib chiqamiz, shundan keyin ancha tushunarli bo'lib qoladi degan umididamiz. Inkapsulyatsiyaning maqsadi - ob'ektning ichki holatini izchil bo'lishini ta'minlash. C# da inkapsulyatsiya uchun ob'ektning umumiy propertys (xususiyatlar) va methods (usullari) qo'llaniladi. Inkapsulyatsiyani oddiy misol bilan tasvirlash mumkin. Aytaylik, biz haqiqiy qiymatni va uning satr ko'rinishini saqlashimiz kerak (masalan, tez-tez foydalanilganda har safar konvertatsiya qilmaslik uchun). Buni avval Inkapsulyatsiyasiz amalga oshirish misolini ko'ramiz:

```csharp
class NoEncapsulation
{
    public double ValueDouble;
    public string ValueString;
}
```

Bu holatda biz Valuening o'zini ham, uning satr tasvirini ham alohida o'zgartirishimiz mumkin va ular qandaydir istisno holatida mos kelmay qolishligi mumkin.

Endi huddi shu narsani Inkapsulyatsiya yordamida amalga oshirib ko'raylik, u holda:

```csharp
class EncapsulationExample
{
    private double valueDouble;
    private string valueString;

    public double ValueDouble
    {
        get { return valueDouble; }
        set 
        {
            valueDouble = value;
            valueString = value.ToString();
        }
    }
}
```

```csharp
public string ValueString
{
    get { return valueString; }
    set 
    {
        double tmp_value = Convert.ToDouble(value);
        valueDouble = tmp_value;
        valueString = value;
    }
}

```

Bu yerda valueDouble va valueString o'zgaruvchilariga faqat ValueDouble va ValueString property (xususiyat)lari orqali kirish mumkin. Agar biz ValueString xususiyatiga yaroqsiz qatorni belgilashga harakat qilsak va konversiya vaqtida istisno yuzaga kelsa, u holda ichki o'zgaruvchilar bir xil, izchil holatda qoladi, chunki istisno protseduradan chiqishga sabab bo'ladi.


# Abstrakt class va funksiyalar

Xondamir Abduxoshimov

&#x20;OOP(Object Oriented Programming) asoslarini o'rganish davomida, e'tiborimizni qaratishimiz lozim bo'lgan bir tushuncha bor. U - *abstraktsiyadur(abstraction)*. Bugun shu haqida gaplashib o'tamiz.

#### Abstraktsiya o'zi nima? <a href="#abstraktsiya-ozi-nima" id="abstraktsiya-ozi-nima"></a>

Abstraktsiya obyektga yo'naltirilgan dasturlash (OOP) tillarining asosiy tushunchalaridan biridir. Uning asosiy maqsadi foydalanuvchidan keraksiz ma'lumotlarni yashirish orqali murakkablikni boshqarishdir. Bu foydalanuvchiga barcha yashirin murakkablikni tushunmasdan, undan foydalanishga imkon yaratadi.

Abstraktsiya faqatgina dasturlashga taaluqli bo'lgan tushuncha emas, uni real hayotimizda ham ko'p javhalarda kuzatishimiz mumkin. Keling bo'lmasa, abstraktsiya tushunchasini, kundalik hayotimizda uchrab turadigan bankomatlardan pul yechish mavzusiga bog'lab ko'ramiz.

#### Abstraktsiya va bankomatdan pul olish <a href="#abstraktsiya-va-bankomatdan-pul-olish" id="abstraktsiya-va-bankomatdan-pul-olish"></a>

> Tasavvur qiling siz talabasiz va bugun sizning bank kartangizga stipendiya tushdi. O'zingizni - o'zingiz mehmon qilish maqsadida, kartadagi mablag'ni naqd ko'rinishga keltirish uchun bankomatga tashrif buyurdingiz. Bankomatdan o'zingizga kerakli bo'lgan summani belgilab, uni naqd ko'rinishida qabul qilib oldingiz.

Ushbu jarayonda siz bilishingiz kerak bo'lgan ish bu - bankomat aparatiga kartani solib, yechilgan pulni qabul qilish. Sizga bankomat aparati o'zi qanday ishlaydi va pulni naqdlash jarayoni qanday bo'ladi - bu ahamiyatsiz. Kimdir bundan xavotirlanib, bankomat aparatini yaratdi, endi u abstrakt vazifasini bajaradi va sizga taaluqli bo'lmagan tafsilotlarni yashiradi. Siz shunchaki ichki dastur haqida hech qanday bilim talab qilmaydigan oddiy interfeys bilan o'zaro aloqada bo'lasiz.

Dasturlashda ham shu kabi tushunchalar o'rinli. Endigi navbatda C# dasturlash tilidan foydalanib mavzuni yanayam mustahkamlaymiz.

#### C# dasturlash tilida abstraktsiya <a href="#c-dasturlash-tilida-abstraktsiya" id="c-dasturlash-tilida-abstraktsiya"></a>

Abstraktsiya tushunchasi asosan sinf va metodlar uchun foydalaniladi va **abstract** kalit so'zi yordamida quriladi.

**Abstrakt sinf**- bu sodda qilib aytganda cheklangan sinf. Ya'ni undan obyekt olish taqiqlangan. Unga kirish uchun, undan voris sinf olish lozim.

**Abstrakt metod** - bu tanasi mavjud bo'lmagan, hamda faqatgina abstrakt sinfda ishlovchi metod hisoblanadi. Uni tanasi esa, voris sinfda taqdim etiladi.

Endi misollar bilan tanishib chiqamiz.

&#x20;**Example 1**

```csharp
using System; 

// abstrakt class 'Hayvonlar' 
public abstract class Hayvolar 
{
    // abstrakt metod 'Ovoz()'
    public abstract void Ovoz();
}

// class 'Hayvolar' dan olingan  voris class 'Sigir'
public class Sigir : Hayvolar 
{
    // Qayta ishlangan 'Ovoz()' metodi
    public override void Ovoz() 
    { 
        Console.WriteLine("Moo");
    }
}

class Program
{
    static void Main(string[] args)
    {
         // Sigir obyektini yaratish
         Sigir sigir_obj = new Sigir();
         
         // abstrakt metodni chaqirish
         sigir_obj.Ovoz();
     }
 }
```

&#x20;**Natija:** Moo

Ota sinfda joylashgan abstrakt metoddan foydalanish avvalida **override** kalit so'zini yozib qo'yish talab etiladi.

Sinfni abstrakt ko'rinishga keltirish, uning ichida faqatgina abstrakt metodlari bo'lishi kerakligini anglatmaydi. Sinfda oddiy metodlardan ham foydalanish mumkin.

&#x20;**Example 2**

```csharp
using System; 

abstract class AbstractClass 
{
    // Abstrakt bo'lmagan metod
    public int AddTwoNumbers(int num1, int num2) 
    {
        return num1 + num2; 
    }
    
    public abstract int MultiplyTwoNumbers(int num1, int num2);
}

class VorisClass : AbstractClass 
{
    public override int MultiplyTwoNumbers(int num1, int num2) 
    {
        return num1 * num2;
    }
}

class Program
{
    static void Main(string[] args)
    {
        VorisClass d = new VorisClass();
        Console.WriteLine($"Yig'indi: {d.AddTwoNumbers(4, 6)}, Ko'paytma: {d.MultiplyTwoNumbers(6, 4)}");
    }
}
```

&#x20;**Natija:** Yig'indi: 10, Ko'paytma: 24

#### Xulosa <a href="#xulosa" id="xulosa"></a>

Abstraktsiya - bu umumiy tushunchadir, uni real dunyoda ham, OOP ga asoslangan dasturlash tillarida ham topishingiz mumkin. Haqiqiy dunyodagi har qanday narsalar, masalan, aytib o'tilgan bankomat aparati yoki hozirgi dasturiy ta'minot loyihangizdagi sinflar va ichki qismni berkituvchi omillar abstraktsiyani ta'minlaydi.

Ushbu abstraktsiyalar, murakkablikni kichikroq qismlarga ajratish orqali ishni ancha osonlashtiradi. Eng asosiysi, siz ularni qanday qilib funksionallikni ta'minlayotganini tushunmasdan turib, foydalanishingiz mumkin bo'ladi.

Qisqacha tarzda tushuntirib bermoqchi bo'lgan narsalarim shular edi. Agarda sizlarda ham bizning jamoamizga qo'shilish istagi bo'lsa 👉[ushbu ](https://t.me/uz_dotnet)telegram guruhga tashrif buyuring.


# String

Farrukh Kholmatov

## **String**

C# dasturlash tilida satr bilan ishlash uchun **String** ishlatiladi. **String** o’zgaruvchisi ikkita tirnoq (" ") bilan o’ralgan belgilar to’plamini o’z ichiga oladi.

```csharp
    string myText = "Hello";
```

**string** kalit so’zi **String** uchun taxallus hisoblanadi, ya’niki **string** && **String** so’zlari o’zaro tengdir va qaysi ko’rinishdan foydalanish esa dasturchining xohishiga bog’liq. **string** tipidagi o'zgaruvchi eng ko'pi bilan 2 Gb ma'lumotni, yoki **1073741791 ta** belgini saqlashi mumkin.

C# dasturlash tilida satr bilan ishlash metodlari **String** sinfida joylashgan va bu sinf satrlarni xavfsiz yaratish, boshqarish va taqqoslash uchun ko'plab metodlarni taqdim etadi.

Misol uchun: Satr uzunligini olish:

```csharp
int value = myText.Length;
//output: value = 5;
```

## String sinfining metodlari:

**CompareTo()** – berilgan satrni boshqa bir satr bilan solishtiradi va bizga **bool** ya’ni **True/False** qiymatda javob qaytaradi

```csharp
string str1 = "Hello";
string str2 = "World";
bool IsSame = str1.CompareTo(str2) == 0;
//output: IsSame = False
```

**ToLower()** – berilgan satrdagi barcha harflarni kichik harflarga o’zgartiradi

```csharp
string str1 = "Hello, WORLD !";
string str2 = str1.ToLower();
Console.Write(str2);
 //output: hello, world !
```

**ToUpper()** – berilgan satrdagi barcha harflarni katta harflarga o’zgartiradi

```csharp
string str1 = "Hello, World !";
string str2 = str1.ToUpper();
Console.Write(str2);
 //output: HELLO, WORLD !
```

**Split()** – berilgan satrni biz kiritgan belgi ajratib turgan qismlarga bo'ladi va yangi massivga yuklaydi:

```csharp
string satr="satr,ustun,katakcha";
string [] massiv=satr.Split(',');
foreach (string a in massiv)
    Console.WriteLine(a);

/* output: 
satr
ustun
katakcha
*/
```

Yuqoridagi misolda vergul satr qismlarini ajratuvchi belgi bo'lib xizmat qildi. Gapda so'zlar ko'pincha probel bilan ajratilgani uchun, vergul o'rniga probel ham yozishimiz mumkin. Yoki qavs ichiga hech narsa yozilmasa, Split() metodi bu belgini probel deb tushunadi:

```csharp
string str = "Hello! How are you?";
string[] myString = str.Split();
//output: 
myString[0] = "Hello!"
myString[1] = "How"
myString[2] = "are"
myString[3] = "you?"
```

**StartsWith()** – berilgan satr biz kiritgan satr bilan boshlanganmi yoki yo'qligini tekshiradi. bool tipida qiymat qaytaradi.

```csharp
string str1 = "Hello World";
string str2 = "He";
bool result = str1.StartsWith(str2);
//output: result = True
```

**Contains()** – berilgan satr tarkibida ko’rsatilgan satr yoki belgi bor yoki yo’qligini tekshiradi. Agar bor bo'lsa *true*, aks holda *false* qiymat qaytaradi.

```csharp
string str1 = "Hello World";
string str2 = "bye";
bool result = str1.Contains(str2);
Console.Write(result);   //output: False

Console.Write(str1.Contains("rld"));  // output: True

Console.Write(str1.Contains('a')); // output: False
```

**IndexOf()** – berilgan satr tarkibida kor’rsatilgan satrni indeksini topib, bizga int tipida qaytarib beradi. Agar berilgan satr tarkibida biz ko'rsatgan satr mavjud bo'lmasa, -1 ni qaytaradi.

```csharp
string str1 = "Hello World";
string str2 = "lo";
int result = str1.IndexOf(str2);
//output: result = 3
```

**Substring()** – berilgan satrning ko’rsatilgan diapazondagi qismini qirqib olib, bizga qaytaradi

```csharp
string str1 = "Hello World";
string str2 = str1.Substring(1, 4);
//output: str2 = "ello"
```

**IsNullOrEmpty()** – berilgan satrni bo’sh yoki null ekanligini tekshiradi. Agar satr bo'sh bo'lsa yoki qiymati null ga teng bo'lsa true, aks holda false qiymat qaytaradi.

```csharp
string name = "";
bool IsEmpty = String.IsNullOrEmpty(name);
//output: True
```

**Concat()** – berilgan ikki satrnni birlashtiruvchi funksiya

```csharp
string FirstName = "Farrukh";
string LastName = "Kholmatov";
string name = string.Concat(Firstname, Lastname);
//output: Farrukh Kholmatov
```

**String.Format && "$"** - satr va obyektlar ustida bir vaqtning o’zida ishlash imkonini beradi

```csharp
string name = "Petr";
int year = 45;
string str = String.Format("Hello {0}, {1}", name, year);
// str = "Hello Petr, 45"
int a = 5;
int b = 7;
string result = $"{a} + {b} = {a + b}";
// str = "5 + 7 = 12"
```

## WARNING!

C# dasturlash tilida "+" (qo’shish) operatori orqali ham qo’shish ham birlashtirish mumkin.

{% hint style="info" %}
**Esda tuting!** *Sonlar qo’shiladi, satrlar birlashadi*
{% endhint %}

```csharp
int num1 = 5;
int num2 = 12;
int result = num1 + num2;
//output: result = 17

string str1 = "6";
string str2 = "9";
string result = str1 + str2;
//output: result = 69
```


# StringBuilder

Niyozbek Mirzayev

C# dasturlash tilida Stringga o'xshash StringBuilder tipi mavjud. Ular bir-biriga yaqin, lekin ma'lum farqlar ularni ajratib turadi.

Keling, StringBuilder qanday yaratilishi haqida bilib olaylik. Avallo, **System.Text** kutubxonasini chaqirishimiz lozim, shundan so'ng quyidagicha kod yoradamida StringBuilder e'lon qilinadi:

```csharp
StringBuilder strB = new StringBuilder(); 
```

Endi esa asosiy qism, ya'ni String va StringBuilderning farqini ko'rib chiqamiz:

**String bu immutable tip hissoblandi, ya'ni uni xotirada e'lon qilganimizdan so'ng uni o'zgartira olmaymiz, StringBuilder esa mutable tip hisoblandi, ya'ni u xotirada o'z ko'rinishni va o'lchamini o'zgartira oladi. Shu sababdan, StringBulider Stringdan tezroqdir.**

Misol uchun, Quyidagi kodda *str* o'zgaruvchisi 1000 martta xotiradan o'chirib tashlanadi va har safar *Salom* so'zi qo'shilib qaytadan yaratiladi.

```csharp
string str = "Salom";  
for (int i = 0; i < 1000; i++)  
{  
     str += "Salom ";  
}
```

Keling end shu misolni StringBuilder orqali ko'raylik:

```csharp
    
StringBuilder strB = new StringBuilder(); 
for (int i = 0; i < 1000; i++)  
{  
     strB.Append("Salom ");  
}
```

str o'zgaruvchisida farqli ravishda strB o'zgaruvchisi xotirada 1000 marta o'chirilib tashlanmaydi, buning o'rniga *strB* o'zgaruvchising o'ziga 1000 martta *Salom* so'zi qo'shilib yoziladi.

Yuqorida ko'rganingizdek StringBuilderning ham String kabi o'z methodlari mavjut va quyida ulardan bir nechtasiga misolar keltirilgan:

* **Append** - StringBuilderning oxiridan String qo'shish uchun ishlatiladi.

```csharp
StringBuilder strB = new StringBuilder("Hello World!!");	
string str = " Yes ";
		
strB.Append(str); 
Console.WriteLine(strB); //output:   Hello World!! Yes 

```

* **AppendLine** - **Append** funksiyasi kabi ishlaydi, lekin har bir **String**ni yangi qatordan qo'shadi:

```csharp
StringBuilder strB = new StringBuilder("Hello World!!");		
string str = " Yes ";
		
strB.AppendLine(str);
//output: Hello World!!
//				Yes
```

* **Remove** -satrning ma'lum indexdan boshqa bir indexgacha bo'lgan qismini o'chiradi:

```csharp
StringBuilder strB = new StringBuilder("Hello World!!");
strB.Remove(0, 11);

Console.WriteLine(strB); 
//output: !!
```

* **Replace** - satrning ma'lum bir qismini boshqa bir satr bilan almashtiradi.

```csharp
StringBuilder strB = new StringBuilder("Hello World!!");
strB.Replace("World", "C#");

Console.WriteLine(strB); 
//output: Hello C#!!
```

* **Clear -** StringBuilder ichidagi barcha ma'lumotlarni o'chirish uchun ishlatiladi:

```csharp
StringBuilder strB = new StringBuilder("Hello World!!");
Console.WriteLine(strB); //output: Hello World!!
strB.Clear();
Console.WriteLine(strB);  //ikkinchi qatorda hech nima chiqmaydi sababi malumotlar o'chirilgan					
```

* **Insert -** Ma'lum bir berilgan indexdan boshlab String qo'shadi:

```csharp
StringBuilder sb = new StringBuilder("Hello World!");
sb.Insert(5," C#"); 

Console.WriteLine(sb);  //output: Hello C# World!
```


# String Intern Pool

Dilafruza Jo'raboyeva

### String Intern pool o'zi nima?

String Intern Pool bu C# dasturlash tilida **literal** e'lon qilingan string'lar saqlanadigan maxsus xotiraning qismi bo'lib, u **LOH**'da joylashgan bir table hisoblanadi. String bilan bog'liq operatsiyalarning ishlash tezligini oshirish va xotiradan samarali foydalanish uchun yaratilgan. String Intern Pool **String Constant Pool** deb ham ataladi.

### String'ni literal e'lon qilish nima degani?

String Intern Pool haqida chuqurroq o'rganishimizdan oldin, biz String'larni **2 xil** tarzda e'lon qilinishini ko'rib chiqishimiz zarur:

1. String'ni literal e'lon qilish:

```csharp
 string s = "Hello, world!";
```

2. String obyektini yaratish orqali e'lon qilish:

   * **new** kalit so'zini ishlatish orqali, String class'ini constructor'ini chaqirgan holatda:

   ```csharp
    string s = new string(new char[] { 'H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!' });
   ```

   * **String Builder** obyektini String obyektiga o'tkazish qilish orqali:

   ```csharp
    StringBuilder sb = new StringBuilder();
    sb.Append("Hello, ");
    sb.Append("world!");
    string s = sb.ToString();
   ```

   * 2 ta String obyektini **birlashtirish** orqali,.. va hokazo:

   ```csharp
    string s1 = "Hello, ";
    string s2 = "world!";
    string s = s1 + s2;
   ```

### String Intern Pool qanday ishlaydi?

* String'lar literal holatda e'lon qilinganda, ular avvaliga CLR tomonidan String Intern Pool'da mavjudligi tekshiriladi. Agar mavjud bo'lsa, ularning address'i bitta qilib qo'yiladi. Agar mavjud bo'lmasa, yangi string obyekti yaratiladi va uning address'i String Intern Pool'ga qo'shiladi.
* String obyektlari yaratilganda, ular String Intern Pool'da mavjud bo'lmaganligi uchun, Heap'da joylashadi. Lekin, biz **String.Intern()** method'ini chaqirib, ularni String Intern Pool'ga qo'shishimiz mumkin. Bu method string obyektini qabul qilib, uni String Intern Pool'da mavjudligini tekshiradi. Mavjud bo'lsa, ularning address'i o'sha string intern'ga reference qilib qo'yiladi, mavjud bo'lmasa, yangi string obyekti yaratiladi va uning address'i String Intern Pool'ga qo'shiladi.

```csharp
 public static string Intern (string str);
 //string obyektini String Pool'ga qo'shish.
```

```csharp
 public static string IsInterned (string str);
 //string obyektini String pool'da joylashgan yoki joylashmaganligini aniqlash.
```

* String Intern Pool'da saqlanadigan string'lar faqatgina string literals va String.Intern() method'ida berilgan string'lar bo'lib, ular hech qachon o'chirilmaydi. Bu esa, String Intern Pool'ning to'lib ketishiga olib kelishi mumkin. Shuning uchun, String.Intern() methodini juda ehtiyotkorlik bilan ishlatish kerak.

### String Intern Pool'ning afzalliklari va kamchiliklari nimalardan iborat?

* String Intern Pool'ning asosiy afzalligi string amallarini ishlash tezligini oshirishi va xotiradan samarali foydalanishidir. Agar biz bir nechta string obyektlarini bir-birini taqqoslashimiz kerak bo'lsa, biz String Intern Pool'da mavjud bo'lgan string'larning manzillarini solishtirishimiz mumkin. Bu esa, string obyektlarining qiymatlarini solishtirishdan ancha tezroq amalga oshadi va xotiradan tejash hisoblanadi.
* String Intern Pool'ning asosiy kamchiligi esa, literal string'larni o'zgaruvchan bo'lmaganligi va hech qachon o'chirilmaydiganligidir. Bu esa, String Intern Pool'ning hajmi to'lib ketishiga va xotirada ko'p joy egallashiga olib kelishi mumkin. Shuning uchun, String Intern Pool'ga faqatgina kerakli va qayta-qayta ishlatiladigan string'larni qo'shish kerak.

### Amaliyot bilan tushunish:

Quyidagi code'da, biz String Intern Pool bilan ishlashni ko'ramiz:

```csharp
 // String'larni literal holatda yaratamiz
 string s1 = "Hello";
 string s2 = "Hello";

 // String obyektlari yaratamiz
 string s3 = new string(new char[] {'H', 'e', 'l', 'l', 'o'});

 // String'larni qiymatlarini solishtiramiz.
 Console.WriteLine("s1 == s2: {0}", s1 == s2); // true
 Console.WriteLine("s1 == s3: {0}", s1 == s3); // true
 Console.WriteLine("s2 == s3: {0}", s2 == s3); // true

 // String'larni address'larini solishtiramiz
 Console.WriteLine("ReferenceEquals(s1, s2): {0}", ReferenceEquals(s1, s2)); // true
 Console.WriteLine("ReferenceEquals(s1, s3): {0}", ReferenceEquals(s1, s3)); // false
 Console.WriteLine("ReferenceEquals(s2, s3): {0}", ReferenceEquals(s2, s3)); // false
```

![Xotirada hozirgacha bo'lgan o'zgarishlar )](/files/JTQVm32giINDfwELfrXX)

Keling, endi shu String obyektimizni String Intern pool'ga olib o'tamiz)

```csharp
 // String obyektimizni String Intern Pool'ga qo'shamiz
 s3 = string.Intern(s3);
 // String'larni manzillarini solishtiramiz
 Console.WriteLine("ReferenceEquals(s1, s3): {0}", ReferenceEquals(s1, s3)); // true
 Console.WriteLine("ReferenceEquals(s2, s3): {0}", ReferenceEquals(s2, s3)); // true
```

Natija:

ReferenceEquals(s1, s3): True

ReferenceEquals(s2, s3): True

Natijadan ko'rinib turibdiki, string'lar literal holatda yaratilganda, ular String Intern Pool'da saqlanadi va ularning manzillari bir xil bo'ladi. String obyektlari yaratilganda, ular xotiraning Heap hududida saqlanadi va ularning manzillari bir biridan farq qiladi. Lekin, agar biz ularni String.Intern() method'iga berib, String Intern Pool'ga qo'shsak, ularning manzillari ham bir xil bo'ladi.

### String Intern Pool nima uchun yaratilgan?

String'lar dasturning katta qismni tashkil etadi. Dastur kodi 70% (taqriban) string'lardan tashkil topgan bo'ladi. C#'da esa string'lar immutable hisoblanadi ya'ni o'zgarmas. Dastur ichida ko'p sonli o'zgarmas string konstantalarini yaratish yoki bir xil string'ni qayta-qayta obyektlar sifatida yaratish, Heap'ga salbiy ta'sir ko'rsatadi. CLR String Intern Pool yordamida string'lardan foydalanishni optimallashtirishga yordam beradi.

**Menda 3ta bir xil literal e'lon qilingan string'im bor, ular bitta address'da joylashsa, agar men bitta string'imni qiymatini o'zgartirsam, shu holatda nima bo'ladi? Hamma string'larni qiymati o'zgaradimi?**

Yo'q, chunki String immutable type, ya'ni o'zgarmas, agar o'sha boshqa string'lar bilan qiymati bir xil bo'lgan string'ga o'zgartirish kiritilsa, masalan, **Concat** amali bajarilsa, so'z qo'shilsa, u xotiradan yangi o'zgaruvchi ochib, shu eski string'dagi qiymatni va yangi qo'shilayotgan ma'lumotni jamlab, o'sha o'zgaruvchiga biriktirib qo'yadi:

```csharp
 using System;

 public class HelloWorld
 {
     public static void Main(string[] args)
     {
         // 2ta string turiga mansub o'zgaruvchilarni e'lon qilamiz:
         string hello = "hello";
         string world = "world";

         // hello o'zgaruvchisiga 2-o'zgaruvchimizni + orqali qo'shishga harakat qilib ko'ramiz.S
	     hello+world;  //Buyerda compilyator xatolik beradi, to'g'ridan to'g'ri qiymatini o'zgatira olmasligimizni bildiradi
            
         // hello o'zgaruvchisiga 2-o'zgaruvchimizni += orqali qo'shishga harakat qilib ko'ramiz.
         hello += world;

         // Console'ga hello o'zgaruvchisining qiymatini chop etamiz
         Console.WriteLine(hello); // Output: hello world
     }
 }
```


# Exception Handling

Mamataliyev Diyobek

Bugun siz bilan xatoliklar(exceptions) haqida gaplashamiz. Dasturda shunday xatolik bo'lsa, toki dastur ishga tushgunigacha kompilyator bu xatoliklarni aniqlay olmaydi. Masalan, murojaat qilingan fayl ko'rsatilgan manzilda mavjud emasligi, nolga bo'lish, massiv elementlariga murojaat qilayotganda massiv chegarasidan chiqib ketish va hokazo. Ishga tushirilgan dasturda shu kabi xatoliklar bo'lsa, xatolik bo'lgan joyda dastur ishi to'xtatilib, xatolik haqida xabar beruvchi oyna ekranga chiqariladi. Bunday xatoliklarga duch kelganingizda dastur logikasini o'zgartirib, xatolik yuzaga keltirmaydigan kod yozishingiz yoki xatolik yuzaga kelganda bajariladigan amallarni belgilash uchun try/catch blokidan foydalanishingiz kerak bo'ladi.

Xatolik(exception)lar yuzaga kelganda, kompilyator har bir xatolik uchun mos bo'lgan alohida xatolik oynasini ekranga chiqaradi:

![System.DivideByZeroException xatoligi](https://user-images.githubusercontent.com/91861166/139944019-846eb307-c9cd-4d75-a4fa-941804064cf7.png)

Yuqoridagi rasmda 7 ni 0 ga bo'lishga urinish tufayli `System.DivideByZeroException` xatoligi yuzaga kelgan.

**try/catch** blokidan foydalanish uchun xatolik sababi va nomini bilishingiz kerak bo'ladi.Endi esa shu kabi xatoliklarni bir-biridan ajratib olish uchun birma-bir tanishib chiqamiz:

### System.DivideByZeroException

Biror sonni nolga bo'lishga urinish tufayli yuzaga keladi.

### System.IO.IOException

Bu sinf fayl va papkalar bilan ishlaganda yuzaga keladigan xatoliklarni o'z ichiga oladi. Masalan:

**System.IO.PathTooLongException** - dastur kodida yangi fayl yoki papka e'lon qilinayotganda unga qo'yilgan nom juda uzun bo'lib ketganda yuzaga keladi. Faylga qo'yiladigan nomning maksimal uzunligi 260 ta belgidan, katalog(papka)ning nomi 248 ta belgidan ortib ketmasligi shart.

**System.IO.UnauthorizedAccessException** - fayl yoki papka ustida bajarish mumkin bo'lmagan amalni bajarishga uringanda yoki xavfsizlik tufayli kirish taqiqlangan fayl/papkaga kirishga uringanda yuzaga keladi. Masalan, faqat o'qish uchun ochilgan faylga yozishga urinishda shu xatolik oynasi ekranga chiqadi.

**System.IO.FileNotFoundException** - mavjud bo'lmagan faylga murojaat qilinganda shu xatolik yuzaga keladi.

**System.IO.DirectoryNotFoundException** - dasturda aslida mavjud bo'lmagan katalog(papka) ko'rsatilishi tufayli yuzaga keladi. Masalan:

```csharp
using System;
using System.IO;
public class program
{
    public static void Main()
    {
        try
        {
            Directory.SetCurrentDirectory(@"c:\newfolder1");
        }
        
        catch (DirectoryNotFoundException e)
        {
            Console.WriteLine(e.Message);
        }
        Console.ReadKey();
    }
}
```

**System.IO.DriveNotFoundException** - mavjud bo'lmagan disk yoki boshqa ulanish orqali murojaat qilinganda yuzaga keladi.

### System.IndexOutOfRangeException

Bu xatolik massivda mavjud bo'lmagan elementga murojaat qilinganda yuzaga keladi. Masalan, quyidagi kabi hollarda:

```csharp
using System;
public class program
{
    public static void Main()
    {
        int[] massiv = new int[] { 1, 2, 3, 4, 5 };
        for (int i = 0; i < 8; i++)
        {
            Console.WriteLine(massiv[i]);
        }
        Console.ReadKey();
    }
}
```

### System.OutOfMemoryException

Operativ xotiraning juda ko'p qismidan foydalanilganda yuzaga keladi. 32 bitli sistema uchun tuzilgan dasturlarda xotiradan foydalanishning maksimum chegarasi **2 Gb**ga, 64 bit uchun tuzilganlarda **4 Gb** ga teng. Xotiradan foydalanish bundan ortib ketishi bilan kompilyator dastur ishlashini to'xtatadi va ushbu xatolik oynasini ekranga chiqaradi.


# try/catch

Hamroliyev Ahmadjon

C# da istisno holat sintaksisi.\[try/catch]

Istisno holat faqat dastur bajarilish vaqtida sodir bo'ladi. Dastur ishlab turgan vaqtdagi kelib chiqadigan xatoliklarni C# ning istisno holatlarni qayta ishlash tizimidan foydalanib boshqariladigan va tizimli qayta ishlash mumkin.\
Istisno holatlarni qayta ishlashning asosiy afzalligi shundan iboratki, bu sizga kodning ko'p qismini avtomatlashtirishga imkon beradi, ilgari har qanday yirik dasturga xatolarni boshqarish uchun qo'lda kiritilishi kerak edi.\
Shunday qilib, agar dastur dasturlash tilida istisnolardan foydalanmasdan yozilgan bo'lsa, unda xato kodlarini qaytaradigan metodlar muvaffaqiyatsiz bajariladi va siz ularni har bir chaqiruvda ularni qo'lda tekshirishga majbur bolasiz.

**System.Exception** namespace C# dagi barcha istisno holatlar malum bir sinflarni ichida saqlanadi. Barcha istisno holatlar joylashgan sinflar **System** namespace(nomlar fazosi)iga kiruvchi C# da o'rnatilgan **Exception** qismidan kelib chiqadi. Shuning uchun barcha istisnolar **System.Exception** namespacening qism sinflariga tegishli.\
Istisno holatining eng muhim **Exception** qism sinfi **System.Exception** namespacega tegishlidir. C # tizimida ishlash vaqtida kelib chiqadigan barcha istisnolar aynan shu sinfdan kelib chiqadi.\
C # dastur tuzuvchilarga ushbu vaziyatlarni boshqarish imkoniyatini beradi.\
Buning uchun C # da **try…catch…finally** konstruktsiyasi mo'ljallangan\
• **try** bloki – dastur bajarishi lozim bo’lgan kodni inkapsulyatsiya qiladi. Agar ushbu jarayonda xatolik yoki mumkin bo’lmagan hol yuzaga kelsa, xatolik sodir bo’lganda bajariladigan blok chaqiriladi.\
• **сatch** bloki – try blokidan so’ng kelib, xatolik yuz berganda bajariladigan kodni ishga tushiradi.\
• **finally** bloki – doimo bajariluvchi kod, yani try blokidan keyin yoki catch blokidan keyin bajariladi. Ushbu blok har doim bo’lishi shart emas. Undan goto operatori orqali chiqish mumkin emas.\
Quyida istisnolardan foydalanish uchun **try/catch/finally** bloklarni aniqlashning umumiy shakli keltirilgan:

```
try  
{  
   // Bu yerda tekshiriluvchi kod turadi   
        // Ushbu kod xatolikni hosil qilishi mumkin  
}  
catch (xatolik turi1)  
{  
   // try blokida xatolik yuzaga kelganda   
         // ushbu kod bajariladi   
}  
catch (xatolik turi2)  
{  
   // try blokida xatolik yuzaga kelganda   
         // ushbu kod bajariladi   
}  
  
finally  
{  
       // Ushbu blokdagi kod yuqoridagi bloklar  
      // bajarilgandan so’ng bajariladi   
}  
```

1-Misol.

```csharp
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
 
namespace dotnetuz 
{ 
  class Program 
  { 
    static void Main(string[] args) 
    { 
      double s, a, x; 
      try 
      { 
          Console.Write("a="); 
          a = Double.Parse(Console.ReadLine()); Console.Write("x="); 
          x = Double.Parse(Console.ReadLine()); 
 
          s = (a * a + Math.Exp(2 * a - 6)) / (x * (a + Math.Pow(2, x))); 
          Console.WriteLine("s=" + s); 
      } 
      catch (SystemException ex) 
      { 
          Console.WriteLine("Ifodaning qiymatini hisoblashda" + ex.Message + " xatolik yuz berdi"); 
      } 
      finally 
      { 
          Console.WriteLine("Ifodaning qiymatini hisoblash tugadi"); 
      } 
      Console.ReadLine(); 
    } 
  } 
} 
```

2-Misol.

```csharp
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
 
namespace dotnetuz 
{ 
  class Program 
  { 
    static void Main(string[] args) 
    { 
      double[] a = new double[10]; 
      double x, s = 0; 
      Console.Write("x=");
      try 
      { 
          x = Double.Parse(Console.ReadLine()); for (int i = 0; i < 10; i++) 
          { 
              a[i] = Double.Parse(Console.ReadLine()); if (x + i != 0) { s += a[i] / (x + i); } else throw new DivideByZeroException(); 
          } 
          Console.WriteLine("s=" + s); 
      } 
      catch (DivideByZeroException) 
      { 
          Console.WriteLine("Ifodani hisoblashda 0 ga bo'lish uchradi"); 
      } 
      catch (IndexOutOfRangeException) 
      { 
          Console.WriteLine("Massivning indeksi chegaradan tashqariga chiqdi"); 
      } 
      catch (SystemException ex) 
      { 
          Console.WriteLine("Xatolik:" + ex.Message +" yuz berdi"); 
      } 
      finally 
      { 
          Console.WriteLine("Dastur tugadi"); 
      } 
      Console.ReadLine(); 
 
    } 
  } 
}
```

![](https://user-images.githubusercontent.com/91861166/139919188-62576945-59c8-44fa-9b13-52386bf257e3.png)

![](https://user-images.githubusercontent.com/91861166/139919605-a4062425-824e-46a8-97ad-95cbb055b0a6.png)

![](https://user-images.githubusercontent.com/91861166/139919631-389eefec-49d6-4fb4-837a-9d62f4bc4c89.png)

![](https://user-images.githubusercontent.com/91861166/139919661-0cd0eddb-da5f-48b5-8d35-735bf400ed61.png)


# finally

Ravshan Sodiqov

Bundan avvalgi darslarimizda try/catch bloki haqida yaxshigina ma’lumotlarni qo’lga kiritigansiz degan umidda ushbu bloklarning finalini ta’minlovchi finally haqida so’z yuritamiz. Dasturlar ba’zida istisno holatlari bilan yakunlangan bo’lishi mumkin, ya’ni dastur tanasining **try { ... }** bloki bajarilmasdan aksincha, dastur **catch { ... }** bloki ichida yakunlangan. Ammo ba’zida dastur xatolik holatiga tushguniga qadar biror yopilishi kerak bo’lgan fayl yoki tarmoqni ochgan bo’lishi mumkin. Bunday ochilgan tarmoq va fayllarni yopish uchun **finally { ... }** blokidan foydalaniladi.

{% hint style="info" %}
**finally** bloki har qanday istisno holati (catch) yoki try bloki bajarilishidan qat’iy nazar bajariladi.
{% endhint %}

"Sizlar nima qilsangiz ham men baribir so’ngida o’z so’zimni aytaman" shiori ostida ish ko’ruvchi blokni amaliy misollarda qaraymiz:

```csharp
try
{
    int a = 0;
    int b = 5;
    Console.WriteLine(b/a);
}

catch(DivideByZeroException)
{
    Console.WriteLine("0 ga bo'lish mumkin emas !");
}

finally
{
    Console.WriteLine("Dastur ishlashi tugallandi.");
} 
```

Yuqoridagi holatda dasturning istisno holati bajarilgach, finally bloki ichidagi kod o’z ishini boshlaydi. Agar o’zgaruvchilarning qiymatlarini misol uchun a = 2, b = 4 tarzida o’zgartirsak, u holda, dasturning catch bloki bajarilmaydi, lekin so’ngida baribir finally bloki ichidagi kod bajarilishini ko’rish mumkin.

Endi yana bir misolni qaraymiz. Faraz qilaylik, ma’lum katalogdagi fayldagi ma’lumotlarni boshqa faylning ma’lumotlariga qo’shish kerak:

```csharp
StreamReader reader = null;
StreamWriter writer = null;
try
{
    reader = new StreamReader(File.Open(@"C:\Users\Public\Documents\file1.txt", FileMode.Open));
    writer = new StreamWriter(File.Open(@"C:\Users\Public\Documents\file2.txt", FileMode.Append, FileAccess.Write));
    while (reader.Peek() != -1)
    {
        writer.WriteLine(reader.ReadLine());
    }

}

catch(Exception ex)
{
     Console.WriteLine(ex);
}
```

Yuqoridagi holatda *file1.txt* faylining ma’lumotlari *file2.txt* ga qo’shilmoqda. Agar *file1.txt* dagi ma’lumotlarni o’qishda yoki *file2.txt* ga ma’lumotlarni yozishda qandaydir xatolik ro’y bersa, dasturning catch bloki bajariladi va xatolik to’g’risida xabar qilinadi. Lekin shuni unutmaslik kerak-ki, dastur catch holatiga tushganda ikkala fayllarning ham holati ochiq holda. Endi ushbu dasturga finally bloki ichida bu ikkala faylni ham yopuvchi kodni yozish eng to’g’ri qaror:

```csharp
StreamReader reader = null;
StreamWriter writer = null;
try
{
    reader = new StreamReader(File.Open(@"C:\Users\Public\Documents\file1.txt", FileMode.Open));
    writer = new StreamWriter(File.Open(@"C:\Users\Public\Documents\file2.txt", FileMode.Append, FileAccess.Write));
    while (reader.Peek() != -1)
    {
        writer.WriteLine(reader.ReadLine());
    }
}

catch(Exception ex)
{
    Console.WriteLine(ex);
}

finally
{
    if(reader != null)
    {
        reader.Close();
    }

    if(writer != null)
    {
        writer.Close();
    }
}

Console.ReadKey(); 
```


# Professional


# To'plamlar

Massivning aka-ukalari

To'plamlar sizning dasturingizda ob'ektlar bilan ishlash usulini standartlashtiradi. Boshqacha qilib aytganda, to'plamlar bu - elementlarni umumlashtirilgan tarzda o'z ichiga olgan sinflar to'plami desak ham bo'ladi. To'plamlar yordamida foydalanuvchi yangilash, o'chirish, qidirish, saralash, tartiblash va h.k. kabi bir nechta operatsiyalarni bajarishi mumkin.

C# da to'plamlar bir nechta sinflarga (class) bo'linadi va eng ko'p ishlatilinadiganlarini quyida keltirganmiz:

![](/files/-Mc9kIB056WFcOzhZ4s7)

### [ArrayList](https://docs.dot-net.uz/c-.net/basic/yuqori-daraja/toplamlar/arraylist)

### [List](https://docs.dot-net.uz/c-.net/basic/yuqori-daraja/toplamlar/list)

### [SortedList](https://docs.dot-net.uz/c-.net/basic/yuqori-daraja/toplamlar/sortedlist)

### [Dictionary](https://docs.dot-net.uz/c-.net/basic/yuqori-daraja/toplamlar/dictionary)

### [HashTable](https://docs.dot-net.uz/c-.net/basic/yuqori-daraja/toplamlar/hashtable)

### [Stack](https://docs.dot-net.uz/c-.net/basic/yuqori-daraja/toplamlar/stack)

### [Queue](https://docs.dot-net.uz/c-.net/basic/yuqori-daraja/toplamlar/queue)


# List

Tolibjonov Abdulloh

**List** - elementlarni va obyektlarni saqlashga moslashgan to'plam. Bu to'plamga **List** deb nom berilishiga sabab, ro'yxatlar bilan qulay ishlash mumkin (tarjimasidan bilib olsa bo'ladi). Ro'yxatda nima qilishimiz mumkin, elementlarni ixtiyoriy joyga qo'shish yoki ixtiyoriy joyidan o'chirib tashlash va tartiblash (sort) funksiyasi borligi bilan boshqa to'plamlardan ajralib turadi.

{% hint style="info" %}
**MUHIM QOIDALAR!**

* List elementlari null qiymat qabul qilishi mumkin
* Elementlari qiymati bir xil bo'lishi mumkin
* Elementlari \[0] indeksdan boshlanadi
  {% endhint %}

## List ni qanday yaratish mumkin?

**1-Bosqich.** Kod yuqorisida using System.Collections.Generic; ni kiritib o'tamiz

```csharp
using System.Collections.Generic;
```

**2-Bosqich.** List shabloni yordamida List yaratamiz

**3-Bosqich.** Element qo'shamiz

Element qo'shishning ikki yo'li mavjud:

1\) Xuddi massivdek, Listni yaratgan zahotingiz elementlarini kiritib qo'yishingiz mumkin

```csharp
List<int> my_list = new List<int>() { 1, 2, 3, 4, 5 };
```

2\) **Add()** va **AddRange()** funksiyasi yordamida ham element qo'shish mumkin

**Add()**

```csharp
List<int> my_list = new List<int>();
my_list.Add(1);
my_list.Add(2);
my_list.Add(3);
my_list.Add(4);
my_list.Add(5);
```

![](/files/-Md3aLK0u7xt5mUZeMKZ)

Elementlar shu tarzda birin ketin joylashib boradi

**AddRange()**

```csharp
List<int> my_list = new List<int>();
my_list.Add(1);
my_list.Add(2);
my_list.Add(3);

int[] array = new int[2];
array[0] = 4;
array[1] = 5;

my_list.AddRange(array);

foreach(int value in my_list)
    Console.WriteLine(value);
```

![](/files/-Md3aLK2w6h6LZNUhGpQ)

Listda **foreach** ni quyidagi usulda ham ishlatish mumkin

```csharp
my_list.ForEach(a => Console.WriteLine(a));
```

Yoki o'zimizni dehqoncha usul ham bor :)

```csharp
for (int a = 0; a < my_list.Count; a++)
{
    Console.WriteLine(my_list[a]);
}
```

## Listga misollar:

```csharp
using System;
using System.Collections.Generic;
class Program
{
   static void Main(string[] args)
   {
       List<int> my_list = new List<int>();
       my_list.Add(101);
       my_list.Add(33);
       my_list.Add(8);
       my_list.Add(616);
       my_list.Add(-5);


       my_list.ForEach(a => Console.WriteLine(a));
    }
}
```

![](/files/-Md3VWXQlLkGXevYxVtw)

## Listni yaratishga yaratib oldik. Endi elementlarni qanday o'chiramiz?

Remove(), RemoveAll(), RemoveAt(), RemoveRange(), Clear() funksiyalari yordamida misollar yozamiz.

**Remove(T)**- birinchi uchragan T elementni o'chiradi. T ni o'rnida Listdagi o'chirmoqchi bo'lgan element qiymatini yozamiz

```csharp
List<int> my_list = new List<int>();
my_list.Add(101);
my_list.Add(33);
my_list.Add(8);
my_list.Add(616);
my_list.Add(-5);


my_list.Remove(101); // my_listdan 101 ni o`chiradi

foreach (var value in my_list)
{
    Console.WriteLine(value);
}
```

![](/files/-Md3VWXR6flz4gQ0A4KM)

**RemoveAll(x=> x==T)** – Listdagi barcha T ga teng bo'lgan elementlari o'chiradi

```csharp
List<int> my_list = new List<int>();
my_list.Add(101);
my_list.Add(33);
my_list.Add(8);
my_list.Add(616);
my_list.Add(616);


my_list.RemoveAll(x => x == 616); //my_listdan barcha 616 ni o`chiradi

foreach (var value in my_list)
{
    Console.WriteLine(value);
}
```

![](/files/-Md3VWXSXa6K2D3s7rPs)

**RemoveAt(index)** - index ni joyiga, Listdagi qaysi elementni o'chirmoqchi bo'lsak, o'sha elementni indeksini yozamiz

```csharp
List<int> my_list = new List<int>();
my_list.Add(101);   //0
my_list.Add(33);    //1
my_list.Add(8);     //2
my_list.Add(616);   //3
my_list.Add(-5);    //4


my_list.RemoveAt(0); //101 ni o`chiradi, chunki indeksi [0]

my_list.RemoveAt(3); //-5 ni o`chiradi chunki indeksi [3]

foreach (var value in my_list)
    Console.WriteLine(value);
```

![](/files/-Md3VWXTtbz43DKkTZkD)

Bu yerda so'rashingiz mumkin (-5) ni o'chirish uchun nega indeksini 3 yozdik, axir indeksi 4 ku? Ha to'g'ri (-5) qiymatli elementni indeksi 4 edi. Ammo 0-indeksdagi (101)ni o'chirganimizdan so'ng elementlari qaytda indekslanadi shunda:

```csharp
my_list.Add(33);    //0
my_list.Add(8);     //1
my_list.Add(616);   //2
my_list.Add(-5);    //3
```

(-5) ning indeksi 3 bo'lib qoladi. Endi esa (-5)ni o'cherish uchun indeksiga 3 yozishimiz kerak bo'ladi.

**RemoveRange(index,index)** – bu funksiya qaysi elementdan qaysi elementga o'chirish kerakligini anglatadi

```csharp
List<int> my_list = new List<int>();

my_list.Add(101);   //0
my_list.Add(33);    //1
my_list.Add(8);     //2
my_list.Add(616);   //3
my_list.Add(-5);    //4


my_list.RemoveRange(0, 3);

foreach (var value in my_list)
  Console.WriteLine(value);
```

Bu yerda 0-indeksdan 3-indeksgacha o'chiriladi (101,33,8). Ammo 3-indeksdagi o'chmaydi(616). Natijada: 616 va -5 qoladi.

![](/files/-Md3VWXVo-gic3JMC7-o)

**Clear()**- bu funksiya Listdagi barcha qiymatlarni o'chirib tashlaydi

```csharp
List<int> my_list = new List<int>();

my_list.Add(101);   //0
my_list.Add(33);    //1
my_list.Add(8);     //2
my_list.Add(616);   //3
my_list.Add(-5);    //4


my_list.Clear();

foreach (var value in my_list)
    Console.WriteLine(value);
```

Hamma element o'chib ketgandan keyin, hech narsa qolmaydi

![](/files/-Md3VWXZ8zW7sf92Jdt9)

## Listni qanday tartiblash mumkin?

**Sort()**- funksiyasi avtomatik tariblab beradi

```csharp
List<int> my_list = new List<int>();

my_list.Add(101);   //0
my_list.Add(33);    //1
my_list.Add(8);     //2
my_list.Add(616);   //3
my_list.Add(-5);    //4


my_list.Sort();

foreach (var value in my_list)
    Console.WriteLine(value);
```

Kichikdan kattaga qarab tartiblanadi

![](/files/-Md3VWXaexE9-iujWTQO)


# ArrayList

Hikmatullayev Sayidrahmatulloh

C# da ArrayList hajmi dinamik ravishda oshib boruvchi umumiy obyektlar to'plamidir.

Demak ArrayList ni dinamik massiv yaratish uchun foydalaniladi, ya'ni massiv hajmi sizning dasturingiz talabiga ko'ra avtomatik kattalashadi yoki kichiklashadi. **ArrayList**da faqat *Object* tipidagi elementlarni saqlash mumkin, demak, siz **ArrayList**dan sonlar, satrlar va boshqa tipdagi ma'lumotlarni, obyektlarni ham saqlashda foydalanishingiz mumkin

1-qadam. ArrayList dan foydalanish uchun `System.Collections` nomlar fazosini qo'shish kerak.

2- qadam. Endi ArrayList e'lon qilishni ko'rib chiqaylik:

```csharp
ArrayList  list=new ArrayList();
```

ArrayList qulayliklari bilan tanishamiz:

**Add()** funksiyasi orqali ArrayListga element qo'shishimiz mumkin.

**AddRange()** orqali ArrayList ga to'plam ham qo'shish mumkin.

**Count** ArrayList elementlari sonini aniqlab beradi.

**Remove()** ArrayList dan biror elementni o'chirish uchun ishlatiladi.

**RemoveAt()** ArrayListdan biror indexdagi elementni o'chirish uchun ishlatiladi.

**RemveRange(n,k)** ArrayListning n-indeksdan boshlab k ta elementlarini o'chirishda foydalaniladi.

**Clear()** ArrayListning barcha elementlarini o'chirish uchin ishlatiladi.

**Sort()** ArrayList elementlarini o'sish tartibida saralaydi.

Umuman olganda bu funksiyalar `System.Collections` dagi barcha to'plamlar uchun ishlaydi.

**Add()** funksiyasini ishlatishni ko'rib chiqaylik.

Misol1:

```csharp
using System; 
using System.Collections;  
namespace dotnetuz
{
    class Program
    {
        static void Main(string[] args)
        {
            ArrayList dasturlash = new ArrayList();//dasturlash nomli Arraylist ochdik
            // element qo'shish
            dasturlash.Add("C#");
            dasturlash.Add("C++");
            dasturlash.Add("C");
            dasturlash.Add("Go");
            dasturlash.Add("Python");
            // foreach orqali listni chop etamiz
            foreach (var dastur in dasturlash)
            {
                Console.Write($"{dastur} ");
            }
        }
    }
}
```

Dastur natijasi:

```
C# C++ C Go Python 
```

Misol2:

Birinchi misolda biz bir turdagi elementlardan foydalandik. Umuman olganda ixtiyoriy turdagi elementlarni qo'shish mumkin. Uni quydagi misolda ko'ramiz.

```csharp
using System; 
using System.Collections;  
namespace dotnetuz
{
    class Program
    {
        static void Main(string[] args)
        {
            ArrayList list=new ArrayList(); //list nomli ArrayList ochdik
            list.Add("dotnetuz");
            var list1 = new ArrayList()     //list1 nomli ArrayList
            {
                1.1,"Csharp",2021,true,null
            };
            int[] arr = { 7, 13, 45 };
            Queue queue1=new Queue();
            
            queue1.Enqueue("C++");
            list.AddRange(list1);   //listga list qo'shish
            list.AddRange(arr); //listga massiv qo'shish
            list.AddRange(queue1); //listga queue qo'shish
            for(int i=0;i<list.Count;i++)
                    Console.WriteLine(list[i]);
        }
    }
}
```

Dastur natijasi:

```
dotnetuz
1.1
Csharp
2021
True

7
13
45
C++
```

**Sort()** funksiyasining ishlatilishi:

Keling tushunish oson bo'lishi uchun 1- misolda Sort() funksiyasini ko'ramiz.

```csharp
using System;
using System.Collections;
namespace dotnetuz
{
    class Program
    {
        static void Main(string[] args)
        {
            ArrayList dasturlash = new ArrayList();//dasturlash nomli Arraylist ochdik
            // element qo'shish
            dasturlash.Add("C#");
            dasturlash.Add("C++");
            dasturlash.Add("C");
            dasturlash.Add("Go");
            dasturlash.Add("Python");
            // foreach orqali listni chop etamiz
            foreach (var dastur in dasturlash)
            {
                Console.Write($"{dastur} ");
            }

            dasturlash.Sort();
            // for orqali chop etamiz

            System.Console.WriteLine();
            for (var i = 0; i < dasturlash.Count; i++)
            {
                Console.Write(dasturlash[i]+" ");
            }
        }
    }
}
```

Dastur natijasi:

```
C# C++ C Go Python 
C C# C++ Go Python
```

**ArayList**ning Sort() metodi *QuickSort* algoritmi bo'yicha saralaydi.


# LinkedList

(AIJavhar) Javohirbek Boyaliyev

LinkedList – ikki tomonlama bog'langan, ulangan to'plam. Ya'ni to'plamning har bir elementi o'zidan bitta oldingi va bitta keying elementning LINK ini saqlaydi. Huddi bular kabi: ⬇️

![](https://user-images.githubusercontent.com/91861166/215412659-31828165-e633-496d-969d-3b02c075ff8a.png)

Ushbu ko'rinishdagi (o'zaro bog'langan) to'plamlarni yaratish uchun:

```csharp
LinkedList<string> people = new LinkedList<string>();
```

kabi code yoziladi. Bu yerda string tipiga mansub people (ODAM) deb nomlangan bo'sh to'plam yaratilish jarayoni.

### LinkedList XUSUSIYATLARI:

LinkedList klassning quyidagi xususiyatlari mavjud: • Count: To'plamda mavjud elementlar miqdori • First: Top'lamdagi birinchi bog'lam • Last: To'plamdagi yakuniy (oxirgi, so'ngi, tugallovchi va shu kabi boshqa so'zlar) bog'lam

![](https://user-images.githubusercontent.com/91861166/215413018-902dee2e-ab15-48b2-a511-486dd630cd12.png)

Bu xususiyatlarni ko'rib chiqamiz:

```csharp
var Ustozlarim = new List<string> { "MuhammadKarim aka", "Temur aka", "Jamshid aka" };

LinkedList<string> Ustoz = new LinkedList<string>(Ustozlarim);
Console.WriteLine(Ustoz.Count);            // 3 
Console.WriteLine(Ustoz.First.Value);    // MuhammadKarim aka
Console.WriteLine(Ustoz.Last.Value);    // Jamshid aka 
```

LinkedList ning ba'zi method lari • AddFirst(T value): to'plamning boshida value qiymatiga ega yangi bog'lam(element)ni kiritadi • AddLast(T value): to'plam oxirida value qiymatiga ega bo'lgan yangi tugunni kiritadi • AddAfter( LinkedList node, T value): node bog'lamidan keyin value qiymatli element qo'shadi • AddBefor( LinkedList node, T value): node bog'lamidan oldin value qiymatli element qo'shadi • RemoveFirst(): to'plamdan birinchi bog'lamni o'chirib tashlaydi. Shundan so'ng, o'chirilgan tugundan keying tugun birinchilikka o'tadi. • RemoveLast(): to'plamdagi oxirgi bog'lam(element)ni o'chiradi.

Nazariy bildik, endi ba'zi methodlarni amalda qo'llab ko'ramiz:

```csharp
var people = new LinkedList<string>();
people.AddLast("Abror"); //To'plamning eng oxiriga “Abror” elementini qo'shadi. 
//Bizning vaziyatda to'plamimiz bo'sh shu sababdan bu to'plamning birinchi elementi bo'ladi.

people.AddFirst("MuhammadAmin "); // “MuhammadAmin” qiymatli elementni to'plamning boshiga joylashtiradi.

//Endi esa 1-bog'lam(element)dan keyin element qo'shishni ko'ramiz:
if (people.First != null) people.AddAfter(people.First, "Asadulloh");
 
// Bizning to'plam quyidagi ko'rinishga keladi: 
// Abror MuhammadAmin Asadulloh
foreach (var person in people) Console.WriteLine(person);
```

LinkedList haqida yana qisqacha:

![](https://user-images.githubusercontent.com/91861166/215413108-71f53bd9-966c-427e-a715-d01bb4034921.png)


# SortedList

Tolibjonov Abdulloh

SortedList ham xuddi Listga o\`xshash to\`plam. Elementlarni qo\`shish, o\`chirish, saralash kabi funksiyalar SortedListda ham mavjud. Ammo Listdan farqi elementlar kalit/qiymat tarzida bo\`ladi. Bu qanday bo\`ladi deysizmi? Har bir element qiymatini o\`z kaliti bo\`ladi.

| **1**          | **2**    | **3** | **4**   | **5**    |
| -------------- | -------- | ----- | ------- | -------- |
| Muhammad Karim | Xondamir | Jasur | Farrukh | Abdulloh |

Masalan bu rasmda,

1 – kalitda Muhammad Karim

2 – kalitda Xondamir

3 – kalitda Jasur

4 – kalitda Farrukh

5 – kalitda Abdulloh turadi degani.

MUHIM QOIDALAR !

* SortedListda elementga nafaqat indeksi orqali balki, kaliti orqali ham kirish mumkin
* Kalit null qiymat qabul qilmaydi, ammo element null qiymatni qabul qiladi.
* Bir xil qiymatli elementlar bo\`lishi mumkin, ammo ularning kalitlari bir xil bo\`lmaydi
* Kalitlarni faqat sonlar emas balki ixtiyoriy tipda ham berishingiz mumkin, faqatgina kalitlarning hammasi bir xil tipda bo\`lishi kerak, aks holda kompilyator ishlamaydi

**SortedListni qanday yaratamiz ?**

### 1-bosqich *\*\**

Kod yuqorisiga using System.Collections; ni yozib qo\`ying

### 2-bosqich

Berilgan sintaksis bo\`yicha SortedList yaratamiz

```csharp
SortedList list_nomi = new SortedList();
```

list\_nomi degan joyga o\`zingiz ixtiyoriy nom berishingiz mumkin !

### **3-bosqich Element qo\`shamiz 2 xil usulda :**

1\) SortedListni yaratiboq elementlarni yoniga yozib qo\`ying (xuddi massivdek)

```csharp
SortedList list = new SortedList() 
{ 
    {1, "Abdullajon" }, 

    {2, "Shum bola" },

    {3, "Sariq dev" }  
};
```

Ahamiyat bersangiz elementlar ham jingalak qavs ichida yoziladi, sababi kompilyator kaliti qaysi qiymatga tegishli ekanini aniqlashda xato qilmasligi uchun.

2\) Add() funksiyasi yordamida qo\`shish mumkin

```csharp
SortedList list = new SortedList();
list.Add(1, "Abdullajon");
list.Add(2, "Shum bola");
list.Add(3, "Sariq dev");
```

**4-bosqich**

**Elementlarga kirish GetKey() va GetByIndex()**

```csharp
SortedList list = new SortedList();
list.Add(1, "Abdullajon");
list.Add(2, "Shum bola");
list.Add(3, "Sariq dev");

for(int i = 0; i < list.Count; i++)
{
    Console.WriteLine($"{list.GetKey(i)} - {list.GetByIndex(i)}");
}
```

**Natija:**

![](/files/-MdgooTE4gIutK2iixdq)

GetKey(i) – i element turgan indeksi, indeksiga qarab elementning kalitini aniqlab berad&#x69;**.** GetByIndex(i) – i indeksiga qarab element qiymatini aniqlab beradi

```csharp
SortedList list = new SortedList();
list.Add(1, "Abdullajon");
list.Add(2, "Shum bola");
list.Add(3, "Sariq dev");

string x = (string)list[2];

Console.WriteLine(x);
```

Natija:

![](/files/-MdgpGptW3XWnZwkFIpq)

```csharp
SortedList list = new SortedList();

list.Add(1, "Abdullajon"); // pair
list.Add(2, "Shum bola"); // pair
list.Add(3, "Sariq dev");// pair

foreach(DictionaryEntry pair in list)
{
    Console.WriteLine($"{pair.Key} - {pair.Value}");
}
```

Natija:

![](/files/-MdgpSCAfN6DY0aw3TPM)

**SortedListga misollar**

```csharp
using System;
using System.Collections;

namespace ConsoleApp11
{
    class Program
    {
        static void Main(string[] args)
        {
            SortedList list = new SortedList();

            list.Add(1, "Lambo");
            list.Add(2, "Mercedes"); 
            list.Add(3, "BMW");
            list.Add(4, "RoLLs");
            list.Add(5, "BentLey");

            foreach (DictionaryEntry pair in list)
            {
                Console.WriteLine($"{pair.Key} - {pair.Value}");
            }
        }
    }
}
```

Natija:

![](/files/-Mdgpn09V99OghRXvQmh)

## SortedList dan elementlarni o\`chirish

### Clear() Remove() RemoveAt()

Clear() - funksiyasi to'plamdagi barcha elementlarni o'chirib tashlaydi

```csharp
SortedList list = new SortedList();

list.Add(1, "Lambo");
list.Add(2, "Mercedes"); 
list.Add(3, "BMW");
list.Add(4, "RoLLs");
list.Add(5, "BentLey");

list.Clear();

foreach (DictionaryEntry pair in list)
{
    Console.WriteLine($"{pair.Key} - {pair.Value}");
}
```

Natija:

![](/files/-MdgqIan0ovc9KM5QENQ)

Remove(T) – T-da turgan elementni o\`chiradi, T-indeksda turgan elementni emas.

```csharp
SortedList list = new SortedList();

list.Add(1, "Lambo");
list.Add(2, "Mercedes"); 
list.Add(3, "BMW");
list.Add(4, "RoLLs");
list.Add(5, "BentLey");

list.Remove(3);// 3-elementni o`chiradi, 3-indeksdagini emas

foreach (DictionaryEntry pair in list)
{
    Console.WriteLine($"{pair.Key} - {pair.Value}");
}
```

Natija:

![](/files/-MdgqiMBPjk1VudVUN1U)

### RemoveAt()

```csharp
SortedList list = new SortedList();

list.Add(1, "Lambo");
list.Add(2, "Mercedes"); 
list.Add(3, "BMW");
list.Add(4, "RoLLs");
list.Add(5, "BentLey");

list.RemoveAt(3);

foreach (DictionaryEntry pair in list)
{
    Console.WriteLine($"{pair.Key} - {pair.Value}");
}
```

Natija:

![](/files/-MdgqvDhX7HTZhKKoPv2)

{% hint style="info" %}
Eslatma! Remove() bilan RemoveAt() funksiyalarida qaysi element o\`chib ketganiga ahamiyat bering ular bir xil emas.
{% endhint %}

## Element bor yoki yo\`qligini tekshirish

### Contains(), ContainsKey(), ContainsValue()

Contains() va ContainsKey() funksiyalari bir xil

```csharp
SortedList list = new SortedList();

list.Add(1, "Lambo");
list.Add(2, "Mercedes"); 
list.Add(3, "BMW");
list.Add(4, "RoLLs");
list.Add(5, "BentLey");

Console.WriteLine(list.Contains(3));//kaliti 3
```

Natija:

![](/files/-Mdgr_Uu9llQBRoD3m26)

Bu funksiya kaliti 3ga teng bo'lgan element bor yoki yo'qligini tekshirib beradi. Bor bo'lsa True, bo'lmasa False.

### ContainsValue()

```csharp
SortedList list = new SortedList();

list.Add(1, "Lambo");
list.Add(2, "Mercedes"); 
list.Add(3, "BMW");
list.Add(4, "RoLLs");
list.Add(5, "BentLey");

Console.WriteLine(list.ContainsValue("Porsche"));
```

Natija:

![](/files/-Mdgs4uMEDptkCGTQMO-)

Bu funksiya kalitni emas, berilgan qiymat bor yoki yo'qligini tekshiradi. Listda Porsche yo'q edi. Shu sababli False.


# Dictionary

Tolibjonov Abdulloh

**Dictionary** "TKey, TValue" shablonidagi klass bo'lib, **System.Collection.Generics** namespace sida joylashgan. **Dictionary** kalitlar va qiymatlar to'plami bo'lib, boshqa to'plamlar kabi kalit/qiymat ko'rinishida element qabul qiladi. **Hashtable** dan farqi, **Dictionary** da qidirish tizimi tezroq

```csharp
    using System.Collections.Generic;
```

{% hint style="info" %}
**MUHIM QOIDALAR!**

• Kalitlar bir xil bo'lmasligi kerak

• Kalit null qiymat qabul qilmaydi
{% endhint %}

## Misol:

```csharp
     Dictionary<string, string> Mdic = new Dictionary<string, string>();

            Mdic.Add("1", ".NET");   //1 juftliklar soni
            Mdic.Add("2", "C#");     //2
            Mdic.Add("3", "Asp.NET");//3
            Mdic.Add("4", "LINQ");   //4

            Console.WriteLine($"juftliklar soni : {Mdic.Count}");

            foreach (var item in Mdic)
            {
                Console.WriteLine($"Kalit = {item.Key}  Qiymat = {item.Value}");
            }
```

![](/files/-MePZ40utSEj7lZTEoc7)

```csharp
    Dictionary<string, string> Mdic = new Dictionary<string, string>();

            Mdic.Add("1", ".NET");   //1 juftliklar soni
            Mdic.Add("2", "C#");     //2
            Mdic.Add("3", "Asp.NET");//3
            Mdic.Add("4", "LINQ");   //4

            Console.WriteLine($"juftliklar soni : {Mdic.Count}");

            Dictionary<string, string>.KeyCollection KColl = Mdic.Keys;

            foreach (var item in KColl)
            {
                 Console.WriteLine($"kalit - {item}");
     }
```

![](/files/-MePZ40v8aIngo_3RaMr)

```csharp
    Dictionary<string, string> Mdic = new Dictionary<string, string>();

            Mdic.Add("1", ".NET");   //1 juftliklar soni
            Mdic.Add("2", "C#");     //2
            Mdic.Add("3", "Asp.NET");//3
            Mdic.Add("4", "LINQ");   //4

            Console.WriteLine($"juftliklar soni : {Mdic.Count}");

            Dictionary<string, string>.ValueCollection VColl = Mdic.Values;

            foreach (var item in VColl)
            {
                Console.WriteLine($"qiymat - {item}");
            }
```

![](/files/-MePZ40xchLHzER_lpyE)

```csharp
   static void Main(string[] args)
        {
            Dictionary<string, string> Mdic = new Dictionary<string, string>();

            Mdic.Add("1", ".NET");   //1 juftliklar soni
            Mdic.Add("2", "C#");     //2
            Mdic.Add("3", "Asp.NET");//3
            Mdic.Add("4", "LINQ");   //4

            Console.WriteLine($"juftliklar soni : {Mdic.Count}");

            Console.WriteLine("Clear........");
            Mdic.Clear(); // hamma elementlarni o`chirib yuboradi

            Console.WriteLine($"juftliklar soni : {Mdic.Count}");
        }
```

![](/files/-MePZ40ygRRfQKAbEqPm)

```csharp
    static void Main(string[] args)
        {
            Dictionary<string, string> Mdic = new Dictionary<string, string>();

            Mdic.Add("1", ".NET");   //1 juftliklar soni
            Mdic.Add("2", "C#");     //2
            Mdic.Add("3", "Asp.NET");//3
            Mdic.Add("4", "LINQ");   //4

            Console.WriteLine($"juftliklar soni : {Mdic.Count}");

            foreach (var item in Mdic)
            {
                Console.WriteLine($"kalit - {item.Key}   qiymat - {item.Value}");
            }

            Console.WriteLine("****************************");

            Mdic.Remove("1"); //kaliti 1 ga teng bo`lgan juftlikni o`chirib tashlaydi
            Mdic.Remove("2"); //kaliti 2 ga teng bo`lgan juftlikni o`chirib tashlaydi

            Console.WriteLine($"juftliklar soni : {Mdic.Count}");

            foreach (var item in Mdic)
            {
                Console.WriteLine($"kalit - {item.Key}   qiymat - {item.Value}");
            }
        }
```

![](/files/-MePZ40zOM-gmqiBKc5z)


# HashTable

Tolibjonov Abdulloh

Bu mavzuni boshlashdan oldin Hash kod va Hash jadval haqida bilib olsak !

Hash kod – Ma'lumotlar to'plamida qidiruv va kiritishga yordam beruvchi, hash jadvalga asoslangan raqamli qiymat.

Hash jadval – bu kalit/qiymat elementlarni saqlash uchun maxsus to'plam. Stack, Array, List va Queue ni o'rniga Hash jadval 2 xil qiymat saqlaydi (kalit va qiymat).

**Hashtable** – Hash kodga asoslangan, kalit/qiymat ko'rinishidagi juft elementlar to'plami. Boshqacha qilib aytganda, Hashtable ma'lumotlarni saqlash uchun hash jadvaldan foydalanadi (hash table). Hashtable (non-generic) generic bo'lmagan to'plamdir, shu sababdan kodni yuqorisiga System.Collections ni yozish kifoya.

{% hint style="info" %}
**MUHIM QOIDALAR!**

• Hashtable kaliti null qiymatli bo'lishi mumkin emas

• Hashtable elementlari kalit/qiymat juftligida bo'ladi

• Kalitni nomi boshqa kalitlar bilan bir xil bo'lmasligi kerak
{% endhint %}

## Hashtable ni qanday yaratamiz ?

**1-Bosqich.** Kod yuqorisiga using System.Collections; kiritamiz

```csharp
    using System.Collections.Generic;
```

**2-Bosqich.** Ko'rsatilgan tartibda **Hashtable** ni yaratamiz

```csharp
    Hashtable hashtable_nomi = new Hashtable();
```

hashtable\_nomi – bu Hashtable nomi ixtiyoriy nom yozishingiz mumkin

**3-Bosqich.** Element qo'shamiz, har doimgidek 2 xil usulda :) 1) Hashtable ni yaratiboq element qo'shing (xuddi massivdek)

```csharp
    Hashtable hashtable_nomi = new Hashtable() {{1, "element1"}, {2, "element2"}};
```

2\) Add() funksiyasi yordamida element qo'shing

```csharp
     Hashtable hashtable_nomi = new Hashtable();
        hashtable_nomi.Add(1, "element1");
        hashtable_nomi.Add(2, "element2");
        hashtable_nomi.Add(3, "element3");
```

## Misol:

```csharp
  using System;
  using System.Collections;
  public class Program
  {
      public static void Main()
      {
         Hashtable hashtable_nomi = new Hashtable();
         hashtable_nomi.Add(1, "element1");
         hashtable_nomi.Add(2, "element2");
          hashtable_nomi.Add(3, "element3");
          foreach (DictionaryEntry t in hashtable_nomi)
          {
              Console.WriteLine($"kalit: {t.Key} qiymat: {t.Value}");
          }
      }
  }
```

![](/files/-Mdx4wzzjbVuTJcgq8Uu)

DictionaryEntry haqida SortedList mavzusidagi misollar davomida ma'lumot berib o'tilgan.

## Hashtable da elementlarni qanday o'chiramiz ?

**Remove()** va **Clear()** funksiyalari orqali

**Remove()** – funksiyasidan foydalanib kalitni kiritish orqali elementlarni o'cherish mumkin

**Clear()** – funksiyasi **Hashtable** dagi barcha elementlarni o'cherish uchun

## Misol:

```csharp
  using System;
  using System.Collections;
  public class Program
  {
      public static void Main()
      {
         Hashtable hashtable_nomi = new Hashtable();
         hashtable_nomi.Add(1, "element1");
         hashtable_nomi.Add(2, "element2");
         hashtable_nomi.Add(3, "element3");
         hashtable_nomi.Remove(2);
         foreach (DictionaryEntry t in hashtable_nomi)
          {
              Console.WriteLine($"kalit: {t.Key} qiymat: {t.Value}");
         }
          Console.WriteLine("*********************************");
          hashtable_nomi.Clear();
          foreach (DictionaryEntry t in hashtable_nomi)
          {
              Console.WriteLine($"kalit: {t.Key} qiymat: {t.Value}");
          }
      }
  }
```

![](/files/-Mdx4x-0Wh_CqlYf9Afg)

## Hashtable elementlarni bor yoki yo'qligini qanday bilamiz?

**Contains()** – funksiyasi Hashtableda bizga kerakli kalit bor yoki yo'qligini tekshriadi

**ContainsKey()** – Contains() bilan bir xil

**ContainsValue()** – funksiyasi Hashtableda bizga kerakli qiymat bor yoki yo'qligini tekshiradi

## Misol:

```csharp
  using System;
  using System.Collections;
  public class Program
  {
      public static void Main()
      {
          Hashtable hashtable_nomi = new Hashtable();
          hashtable_nomi.Add(1, "element1");
          hashtable_nomi.Add(2, "element2");
          hashtable_nomi.Add(3, "element3");
          Console.WriteLine(hashtable_nomi.Contains(1));
          Console.WriteLine(hashtable_nomi.ContainsKey(6));
          Console.WriteLine(hashtable_nomi.ContainsValue("element3"));
      }
  }
```

![](/files/-Mdx4x-2xJd819HCvzgN)

**True** bo'lganini sababi Hashtable kaliti 1 ga teng bo'lgan elementi bor

**False** bo'lganini sababi kaliti 6ga teng bo'lgan elementi yo'q

**True** bo'lganini sababi Hashtable ni qiymati "element3" ga teng bo'lgan elementi bor


# Stack

Mamataliyev Diyorbek

To’plamlar bilan tanishishda davom etamiz. Biz o’rganadigan yangi to’plam – **Stack** avvalgilaridan boshqacharoq xossalarga ega. Stack shunday to’plamki, unga yangi elementni faqat ustidan qo’shish mumkin, elementni undagi elementni olib tashlash ham uning ustidan bajariladi. Shuning uchun Stack ni *LIFO* (*Last In First Out*) collection deb ham aytiladi. Ya’ni, **Stack**ga eng oxiri qo’shilgan element undan eng birinchi bo’lib chiqib ketadi.

**Stack**ni yaxshiroq tasavvur qilishingiz uchun hayotiy misol sifatida rasmdagi idishga solingan sharlarni misol qilib keltirishimiz mumkin:

![Stackga misol - idishdagi sharchalar](https://user-images.githubusercontent.com/91861166/138088109-0772ccdb-fd2f-48c8-9148-2268e6a8718f.jpg)

Sharchalardan birorta olishimiz kerak bo’lsa faqat eng ustidan boshlab olish imkoniyatimiz bor(o’rtasidan yoki oxiridan emas). Yangi sharchani qo’ymoqchi bo’lsak ham eng ustiga qo’ya olamiz. Demak biz **Stack** to’plami ustida quyidagi amallarni bajara olamiz:

**Push()** – **Stack**ga yangi element qo’shadi. Element Stackga eng yuqorisidan qo’shiladi (huddi quyidagi rasmdagidek);

**Pop()** – **Stack**ga oxirgi qo’shilgan element qiymatini qaytarib, bu elementni Stackdan olib tashlaydi. Elementni olib tashlanayotganda oxiri qo’shilgani birinchi bo’lib chiqib ketadi;

**Peek()** – **Stack**ning eng yuqorisidagi (oxirgi qo’shilgan) element qiymatini qaytaradi, lekin Stackdan olib tashlamaydi;

**Count** – **Stack**dagi elementlar sonini qaytaradi;

**Clear()** – **Stack**dagi barcha elementlarni o’chirib yuboradi. Bundan so’ng Stackdagi elementlar soni 0 ga teng bo’lib qoladi;

**Contains()** – **Stack**da biror element bor yoki yo’qligini tekshiradi. Bor bo’lsa *true*, yo’q bo’lsa *false* qiymat qaytaradi.

![Push va Pop amallari](https://user-images.githubusercontent.com/91861166/138085847-b8285bf1-dc86-483e-9ab6-e42b91ad4d62.jpg)

Savol tug’ilishi mumkin: Shuncha cheklovlarga ega bo’lgan to’plam dasturlashda nima uchun kerak? Biror qulayligi bormi? Albatta. Masalan, siz ko’p marta ishlatadigan **Undo/Redo** (**Ctrl+Z/Ctrl+Y**) ni ishlatganingizda bajargan ishlaringizni Stackga yozib boradi. **Ctrl+Z** qilganingizda oxirgi qilgan amalingiz birinchi bo’lib orqaga qaytadi va boshqa bo’sh stackga joylanadi (ikkinchi stack **Ctrl+Y** qilganingizda kerak bo’ladi). Yoki yana bir misol brauzeringizdagi avvalgi yoki keyingi ochilgan web-sahifalarga o'tish uchun ishlatiladigan **back/forward** tugmachalari ham **Stack** yordamida ishlaydi.

![back va forward tugmachalari](https://user-images.githubusercontent.com/91861166/147650547-33ad91b4-d58b-4f47-825d-37b0bcd04f21.png)

**Stack** haqida tushunchaga ega bo’lgan bo’lsangiz endi uni kodda ishlashini ham ko’raylik. **Stack** to’plami `System.Collections.Generic` nomlar makonida joylashgani uchun avval shu nomlar makonini chaqirishimiz kerak bo’ladi:

```csharp
using System;
using System.Collections;
using System.Collections.Generic;
public class program
{
  public static void Main()
  {
    //yangi bo'sh Stackni e'lon qilish
    var sonlar=new Stack <int>();
        
    //Stackga yangi elementlarni qo'shish
    sonlar.Push(2);
    sonlar.Push(5);
    sonlar.Push(7);
        
    //Stackdagi elementlar soni:
    Console.WriteLine(sonlar.Count);  //3 
        
    //Stackdan oxirgi qo'shilgan element qiymatini pop() orqali olish
    int b=sonlar.Pop();  //7 ga teng element Stackdan chiqib ketdi
    Console.WriteLine("b="+b);
    Console.WriteLine("Elementlar soni: "+sonlar.Count); //2
        
    //Stackdan oxirgi qo'shilgan element qiymatini peek() orqali olish
    int c=sonlar.Peek();  //Stackdagi elementlar soni o’zgarmadi
    Console.WriteLine("c="+c);
    Console.WriteLine("Elementlar soni: "+sonlar.Count);
        
    Console.ReadKey();
  }
}
```

output:

```
b=7
Elementlar soni: 2
c=5
Elementlar soni: 2
```

Shuning bilan darsimiz nihoyasiga yetdi. Agar Stack to'plamini sizga yaxshi tushuntira olgan bo'lsam xursandman. E'tiboringiz uchun rahmat.


# Queue

Mamataliyev Diyorbek

Assalomu alaykum. Bugun ham to’plamlar bilan tanishishda davom etamiz. **Queue** to’plami haqida tasavvurga ega bo’lish uchun navbatga turgan odamlarni tasavvur qiling. Navbatga kim oldinroq qo’shilgan bo’lsa, o’sha oldinroq chiqib ketadi. Keyin kelganlar oldin chiqib ketolmaydi (agar shunday qilmoqchi bo’lsa janjal chiqishi hech gap emas). Dasturlashda ham shunday.

![Queue - Navbat](https://user-images.githubusercontent.com/91861166/138449830-fb140975-ad5b-445d-b41a-1f0c795c7110.jpg)

{% hint style="info" %}
**Queue** shunday to’plamki, unga elementni faqat oxiridan qo’shiladi, faqatgina boshidan chiqib keta oladi. **Queue**ga avvalroq qo’shilgan elementlar avvalroq tartib bilan chiqib ketadi. Shuning uchun **Queue**ni *FIFO* - *First In First Out Collection* deb ham ataladi.
{% endhint %}

Biz **Queue** to’plami ustida quyidagi amallarni bajara olamiz:

**Enqueue()** – **Queue** ga yangi element qo’shadi (albatta oxiridan);

**Dequeue()** – **Queue** ning eng boshidagi element qiymatini qaytarib, bu elementni queuedan olib tashlaydi;

**Peek()** – **Queue** ning eng boshidagi element qiymatini qaytaradi, lekin Queue dan olib tashlamaydi;

**Count** – **Queue** dagi elementlar sonini (*int* tipida) qaytaradi;

**Contains()** – **Queue** da berilgan element mavjudligini tekshiradi. Bor bo’lsa true, aks holda false qiymat qaytaradi.

![Enqueue() va Dequeue()](https://user-images.githubusercontent.com/91861166/138450045-526d462b-4ec6-4d58-ad22-356db490a746.png)

**Queue** dasturlashda aynan qaysi holatda ishlatiladi? Bir qurilmaga bir nechta qurilmadan bir vaqtda murojaat qilinadigan holatda, masalan bir nechta kompyuter bitta printerga lokal tarmoq orqali ulanganda yoki internet serverlarda navbatni ta’minlash uchun **Queue**dan foydalaniladi.

**Queue** haqida nazariy tushunchaga ega bo’lgan bo’lsangiz endi kodda ham ko’rsak bo'ladi. **Queue** to'plami `System.Collections.Generic` nomlar makoniga tegishli. Shuning uchun avval shu nomlar makonini ham chaqirishimiz kerak:

```csharp
using System;
using System.Collections;
using System.Collections.Generic;
public class program
{
  public static void Main()
  {
    //yangi Queue e'lon qilish
    var navbat=new Queue<int>();
        
    //Queue ga yangi element qo'shish
    navbat.Enqueue(2);
    navbat.Enqueue(5);
    navbat.Enqueue(8);
    navbat.Enqueue(13);
    navbat.Enqueue(21);
       
    //Queue ning eng boshidagi elementni aniqlash
    Console.WriteLine("Eng boshidagi element: "+navbat.Peek());
       
    //Queuedan elementlarni chiqarib tashlash
    Console.WriteLine(navbat.Dequeue()+" soni chiqarib yuborildi");
    Console.WriteLine(navbat.Dequeue()+" soni chiqarib yuborildi");
        
    //Queueda element borligini tekshirish
    Console.WriteLine(navbat.Contains(13));
        
    Console.Write("Queueda qolgan elementlar: ");
    foreach(int a in navbat)
        Console.Write(a+" ");
        
    Console.ReadKey();
  }
}
```

output:

```
Eng boshidagi element: 2
2 soni chiqarib yuborildi
5 soni chiqarib yuborildi
True
Queueda qolgan elementlar: 8 13 21
```

Maqola siz uchun foydali bo'ldi degan umiddaman. E'tiboringiz uchun rahmat.


# Tuple

Javohir Buzrukov

Keling bu mavzuni sodda qilib o'rganish uchun o'xshatish metodidan foydalanamiz :) O'zimiz bilgan, tushungan massiv ga o'xshatib ko'ramiz shunda soddaroq bo'ladi. Qani ketdik.

Tuple classi ni massivga o'xshagan to'plam deb qarasak boladi. Undan farqi har-xil turdagi ma'lumotlarni saqlash mumkin. Keling uni sintaksisi bilan tanishamiz:

```csharp
Tuple<int, string, string> person = new Tuple <int, string, string>(1, "Steve", "Jobs");

//yoki 

var person = Tuple.Create(1, "Steve", "Jobs");
```

Tuple da ko'pi bilan 8 ta element saqlash mumkin. Agar undan ko'payib ketsa, kompilyator bizga xatolik beradi. Lekin bunda ham yechim bor har doimgidek ayyorlik ishlatamiz :) Tuple ichida tuple yozamiz quyidagicha:&#x20;

```csharp
var numbers = Tuple.Create(1, 2, Tuple.Create(3, 4, 5, 6, 7,  8), 9, 10, 11, 12, 13 );
```

Tuplega murojat class maydonlariga murojaat qilishga o'xshab ketadi.&#x20;

{% hint style="success" %}
obyektNomi.Item1, obyektNomi.Item2 ... obyektNomi.Item8&#x20;
{% endhint %}

```csharp
var person = Tuple.Create(1, "Steve", "Jobs"); 

person.Item1; // returns 1 

person.Item2; // returns "Steve" 

person.Item3; // returns "Jobs"
```

8 - elementga **person.Rest** ko'rinishda murojat qilsa ham bo'ladi. **person.Item8** dan farqi Rest qiymatni qovus ga olib chiqaradi.

{% hint style="info" %}
&#x20;E'tibor bering faqat 8- elementga oxirgi elementga EMAS
{% endhint %}

```csharp
var numbers = Tuple.Create("One", 2, 3, "Four", 5, "Six", 7, 8);
Console.WriteLine(numbers.Item1); // print "One"
Console.WriteLine(numbers.Item2); // print 2
Console.WriteLine(numbers.Item3); // print 3
Console.WriteLine(numbers.Item4); // print "Four"
Console.WriteLine(numbers.Item5); // print 5
Console.WriteLine(numbers.Item6); // print "Six"
Console.WriteLine(numbers.Item7); // print 7
Console.WriteLine(numbers.Rest);  // print (8)
Console.WriteLine(numbers.Rest.Item1); // print 8

```

Tupledan, funksiyalarda argument sifatida foydalanish ham mumkin.

```csharp
static void Main(string[] args)
{
    var person = Tuple.Create(1, "Steve", "Jobs");
    DisplayTuple(person);
}

static void DisplayTuple(Tuple<int,string,string> person)
{
    Console.WriteLine($"Id = { person.Item1}");
    Console.WriteLine($"First Name = { person.Item2}");
    Console.WriteLine($"Last Name = { person.Item3}");
} 
```

Funksiylardan Tuple toifasiga mansub qiymatlarni ham qabul qilib olishimiz mumkin:

```csharp
static void Main(string[] args)
{
    var person = GetPerson();
}

static Tuple<int, string, string> GetPerson() 
{
    return Tuple.Create(1, "Bill", "Gates");
}
```

### Tupledan foydalanishning afzallik va kamchiliklari

Qulayliklari:

* Funksiyalardan bir necha qiymatlarnii qabul qilish / yuborish
* Key/Value ko'rinishida ishlash imkoniyati

Kamchiliklari:

* string toifasi kabi Tuple **immutable** tur hisoblanadi. Yaratilgandan keyin uning qiymatlariga o'zgartirish kiritib bo'lmaydi.
* Tuple qiymatli emas balki ma'lumotli (reference) toifa hisoblanadi. Buning hisobiga, u CPU ya'ni protsessorni zo'riqishga olib keladi.


# ValueTuple

Hikmatullayev Sayidrahmatulloh

*C# da ValueTuple.*

**Tuple** bu - bir nechta elmentlardan tuzilgan ma'lumotlar majmuasi .

**ValueTuple** esa **Tuple** ni qiymat turini ifodalaydi.

**Tuple** va **ValueTuple** ni solishtirib ko'raylik.

{% hint style="info" %}

* 1.**Tuple** malum biror son elementlar ketma-ketligi ifodalanadi , **ValueTuple** esa elementlar qiymatlari turini ifodalash mumkin turi.
* 2.**Tuple** larda nol kompanentali kortej yaratishga ruxsat berilmagan , **ValueTuple** da bunday kartej yaratish mumkin.
* 3.**ValueTuple** elementlari o'zgaruvchan .**Tuple** ning elementlari esa faqat o'qish ushun.
  {% endhint %}

**ValueTuple** yaratish strukturasi:

{% hint style="info" %}

* Bitta element uchun

`ValuTuple<T1>(T1)`

* Ikta element uchun

`ValueTuple<T1,T2>(T1,T2)`

.

.

.

* Sakkizta yaratish uchun

`ValueTuple<T1,T2,T3,T4.T5,T6,T7,T8>( T1,T2,T3,T4.T5,T6,T7,T8)`
{% endhint %}

**ValueTuple** ga ham **Tuple** kabi 8 ta element kiritish mumkin xolos.

Lekin bu muammoni **ValueTuple** ichida **ValueTuple** yaratish orqali hal qilish mumkin.

Keling **ValueTuple**ga elementlarni kiritish ko'raylik.

```csharp
using System;
namespace dotnetuz
{
    class Program
    {
        static void Main(string[] args)
        {
            ValueTuple<int> t1 = new ValueTuple<int>(2021);     // t1 nomli bitta elementli valuetuple ochdik
            ValueTuple<string,string,double> t2 = new ValueTuple<string,string,double>("C#","C++",7.1);
            // t2 nomli 3ta elementli valuetuple ochdik
            ValueTuple<int, int, int, int, ValueTuple<int, int>> t3 = new ValueTuple<int, int, int, int, ValueTuple<int, int>>(1, 2, 45, 23,new ValueTuple<int, int>(12, 56));
            //t3 nomli 5 elmentli valuetuple ochdik 
            // ko'rib turganingizdek valuetuple ichida valuetuple ochdik
        }
    }
}
```

**VauleTuple** da ham **Tuple** kabi *Create()* funksiyasidan foydalanish mumkin.

```csharp
using System;
namespace dotnetuz
{
    class Program
    {
        static void Main(string[] args)
        {
            var tuple1 = ValueTuple.Create(); // bo'sh valuetuple yaratdik
            var tuple2=ValueTuple.Create(7.13,"C#","donetuz"); //3ta elementli valuetuple ochdik
            var tuple3 = ValueTuple.Create("C", "C++", "C#", "Python", "Java", "JavaScript", "JavaScript");
        }
    }
}
```

**ValueTuple** da har bir kortej o'z nomiga xususiyatiga ega bo'lish imkoni bor.

Buni quyadagi misolda ko'ramiz.

```csharp
using System;
namespace dotnetuz
{
    class Program
    {
        static void Main(string[] args)
        {
            (string ism, string familya, int yosh) student = ("Sayidrahmatulloh", "Hikmatullayev", 20);
            System.Console.WriteLine(student);
        }
    }
}
```

Qora oynadagi natija.

`(Sayidrahmatulloh, Hikmatullayev, 20)`

**ValueTupe**ning ellementlariga murojat qilishni ko'raylik.

```csharp
using System;
namespace dotnetuz
{
    class Program
    {
        static void Main(string[] args)
        {
            var tuple1 = ("dotnetuz", "Csharp", 2021);
            Console.WriteLine("Sayt :"+tuple1.Item1);
            Console.WriteLine("Dasturlash tili :"+tuple1.Item2);
            Console.WriteLine("Yil :" + tuple1.Item3);
        }
    }
}
```

Qora oynadagi natija.

`Sayt :dotnetuz`

`Dasturlash tili :Csharp`

`Yil :2021`

**ValueTuple** ham **Tuple** kabi elementlariga avtomatik nom beradi .

Lekin elementlarni o'zmiz nomlasak biz uchun ancha qulay bo'ladi.

Keling **ValueTuple** ni elementlarni nomlab murojat qilib koraylik.

```csharp
using System;
namespace dotnetuz
{
    class Program
    {
        static void Main(string[] args)
        {
            var student = (Ism: "Sayidrahmatulloh", Familya: "Hikmatullayev", Yosh: 20);
            Console.WriteLine("Ismi : "+student.Ism);
            Console.WriteLine("Familyasi : "+student.Familya);
            Console.WriteLine($"Yoshi : {student.Yosh}");
        }
    }
}
```

Qora oynadagi natija:

`Ismi : Sayidrahmatulloh`

`Familyasi : Hikmatullayev`

`Yoshi : 20`

Keling endi **ValueTuple** oraqali metod yaratamiz. Metod yaratish dovomida `System.Console` funksiyasini ishlatishni ko'ramiz.

```csharp
using System;
using static System.Console;
 /// <summary>
/// System.Console ni qoshib oldik
/// </summary>
namespace dotnetuz
{
    class Program
    {
        static void Main(string[] args)
        {
            Write(student());   // ko'rib turganingizdek Console.Write emas Write ishlatilgan
            //System.Console bizga shu imkoniyatni beradi.
        }
        static(int ,string ,string ) student()  // metod yaratib oldik
        {
            return (20, "Sayidrahmatulloh", "Hikmatullayev");
        }
    }
}
```

Qora oynadagi natija .

`(20, Sayidrahmatulloh, Hikmatullayev)`

**Metod** ochilganda **ValueTuple**ning elementlariga murojat qlish avvalgi misollar kabi bo'ladi.

**ValueTuple**ni quydagi misolda tushintirishga hatrakat qilaman.

```csharp
using System; 
/// <summary>
/// Alibaba nomli metod ochdik
/// Va Alibaba kompaniya haqida malumotlar kiritish uchun ValueTuple dan foydalandik
/// </summary>
namespace dotnetuz
{
    class Program
    {
        static void Main(string[] args)
        {
            var alibaba = Alibaba();
            Console.WriteLine(alibaba.Kompaniya_tarixi);
        }
        static (string Kompaniya_tarixi,string Foydasi,string Nufuzi ) Alibaba()
        {
            var kompaniya_tarixi = "Alibaba Group Holding Limited — Alibaba Group va Alibaba.com sifatida tanilgan, Xitoyning elektron tijorat, chakana savdo,\n Internet va texnologiyalarga ixtisoslashgan transmilliy texnologik kompaniyasi. \n1999-yil 28-iyunda Chjetszyan shahrining Xanchjou shahrida tashkil etilgan[1].\n Kompaniya veb-portallar orqali isteʼmolchidan isteʼmolchiga (C2C),\n biznesdan isteʼmolchiga (B2C) va biznesdan biznesga (B2B) savdo xizmatlarini taqdim etadi.\n Elektron toʻlov xizmatlari, xarid qilish qidiruv tizimlari va bulutli hisoblash xizmatlari mavjud.\n U dunyodagi ko'plab biznes sohalarida turli xil kompaniyalar portfeliga egalik qiladi va ishlaydi[2]. \nBuyuk Britaniyaning dunyo bozorini o‘rganuvchi «Kantar» kompaniyasi dunyoning eng qimmat kompaniyalari reytingini e’lon qildi. ";
            var foydasi = "25 mlrd AQSh dollar";
            var nufuzi="Jaxon reytingini kuchli o'ntaligida 'Alibab' turadi ";
            return (kompaniya_tarixi,foydasi,nufuzi);
        }
    }
}
```

Qora oynadagi natija:

`Alibaba Group Holding Limited - Alibaba Group va Alibaba.com sifatida tanilgan, Xitoyning elektron tijorat, chakana savdo,` `Internet va texnologiyalarga ixtisoslashgan transmilliy texnologik kompaniyasi.`

`1999-yil 28-iyunda Chjetszyan shahrining Xanchjou shahrida tashkil etilgan[1].`

`Kompaniya veb-portallar orqali iste'molchidan iste'molchiga (C2C),` `biznesdan iste'molchiga (B2C) va biznesdan biznesga (B2B) savdo xizmatlarini taqdim etadi.`

`Elektron to?lov xizmatlari, xarid qilish qidiruv tizimlari va bulutli hisoblash xizmatlari mavjud.`

`U dunyodagi ko'plab biznes sohalarida turli xil kompaniyalar portfeliga egalik qiladi va ishlaydi[2].`

`Buyuk Britaniyaning dunyo bozorini o'rganuvchi «Kantar» kompaniyasi dunyoning eng qimmat kompaniyalari reytingini e'lon qildi.`

Misolda ko'rganimizdek **ValuTuple** orqali o'zimiz uchu kerakli ma'lumotlarni qulay tarzda olishimiz mumkin.

Ya'ni biz o'zimiz uchun **ValueTuple** dagi qaysi element kerak bo'lsa shu elementadan foydalanishimiz mumkin.

**ValueTuple** bizga elementlarni qiymatini o'zgartirish imkoniyatini ham beradi.


# Delegatlar

Nodirbek Abdulaxadov

*Agar funksiyani parametr sifatida uzatishni xohlasak nima bo'ladi? Qanday qilib C# callback funksiyalari yoki eventlarni boshqaradi?*

Javob: **Delegat**

**Delegat** - bu metod imzosini belgilaydigan ma'lumot turi. Siz boshqa ma'lumotlar turi kabi delegatning o'zgaruvchilarini yaratishingiz mumkin va ular yordamida delegat bilan bir xil parametrga ega har qanday metodga murojaat qilishingiz mumkin.

Delegatlar bilan ishlashda uchta bosqich mavjud:

1. Delegatni e'lon qilish
2. Kerakli metodni o'rnatish
3. Delegatni chaqirish

Delegat quyida ko'rsatilgandek , ***delegate*** kalit so'zdan keyin funksiya imzosi yordamida e'lon qilinishi mumkin:

```csharp
[ruxsat modifikatori] delegate [qaytariluvchi tip] [delegat nomi]([parameterlar])
```

Quyida **MyDelegate** deb nomlangan delegat e'lon qilingan:

```csharp
public delegate void MyDelegate(string msg);
```

Yuqorida biz void tipidagi va string parametrli MyDelegate delegatini e'lon qildik. Delegat sinfdan tashqarida yoki sinf ichida e'lon qilinishi mumkin. Quyidagi misolda sinfdan tashqarida e'lon qilamiz.

```csharp
using System;
namespace Delegate
{
    class Program
    {
        // delegat e'lon qilish
        public delegate void MyDelegate(string msg); 

        public static void Main(string[] args)
        {
            // delegat obyektiga metod tayinlash
            MyDelegate del1 = new MyDelegate(MethodA);

            // delegat obyektiga metod tayinlash
            MyDelegate del2 = MethodA;

            //lambda ifodadan foydalanish
            MyDelegate del3 = (string msg) => Console.WriteLine(msg);

            Console.ReadKey();
        }

        //metodni e'lon qilish
        static void MethodA(string message)
        {
            Console.WriteLine(message);
        }
    }
}
```

Kerakli metodni o'rnatgandan so'ng, Invoke() metodi yordamida yoki () operator yordamida delegat chaqirilishi mumkin.

```csharp
del.Invoke("Hello World!");
// or 
del("Hello World!");
```

Quyida delegat qo'llanishining to'liq namunasi keltirilgan:

```csharp
using System;
namespace Delegate
{
    public delegate void MyDelegate(string msg);

    class Program
    {
        static void Main(string[] args)
        {
            MyDelegate del = ClassA.MethodA;
            del("Hello World");

            del = ClassB.MethodB;
            del("Hello World");

            del = (string msg) => Console.WriteLine("lambda ifoda ishlatilishi: " + msg);
            del("Hello World");

            Console.ReadKey();
        }
    }
    class ClassA
    {
        public static void MethodA(string message)
        {
            Console.WriteLine("ClassA.MethodA() metodi chaqirildi: " + message);
        }
    }
    class ClassB
    {
        public static void MethodB(string message)
        {
            Console.WriteLine("ClassB.MethodB() metodi chaqirildi: " + message);
        }
    }
}
```

**Natija:**

![](/files/-McjlUWgyq_1Aebah4p6)

Quyidagi rasm delegatni tasvirlaydi:

![](/files/-McjwViEpaBRgW6uSUWK)

***Delegatni Parametr sifatida uzatish***

Metod quyida ko'rsatilgandek, Delegat turi parametriga ega bo'lishi mumkin:

```csharp
using System;
namespace Delegate
{
    public delegate void MyDelegate(string msg);

    class Program
    {
        static void Main(string[] args)
        {
            MyDelegate del = ClassA.MethodA;
            InvokeDelegate(del);

            del = ClassB.MethodB;
            InvokeDelegate(del);

            del = (string msg) => Console.WriteLine("Lambda ifodaning ishlatilishi: " + msg);
            InvokeDelegate(del);
        }
        static void InvokeDelegate(MyDelegate del) // MyDelegate parametr turi
        {
            del("Hello World");
        }
    }
    class ClassA
    {
        public static void MethodA(string message)
        {
            Console.WriteLine("ClassA.MethodA() metodi chaqirildi: " + message);
        }
    }
    class ClassB
    {
        public static void MethodB(string message)
        {
            Console.WriteLine("ClassB.MethodB() metodi chaqirildi: " + message);
        }
    }
}
```

***Ko'p tarmoqli(Multicast) delegat***

Delegat bir nechta metodlarni ko'rsatishi mumkin. Bir nechta metodni ko'rsatadigan delegat ***ko'p tarmoqli*****(Multicast) delegat** deb ataladi. "+" yoki "+ =" operatori chaqiruvlar ro'yxatiga funksiyani qo'shadi va "-" yoki "-=" operatorlari uni o'chirib tashlaydi.

```csharp
using System;
namespace Delegate
{
    public delegate void MyDelegate(string msg);

    class Program
    {
        static void Main(string[] args)
        {
            MyDelegate del1 = ClassA.MethodA;
            MyDelegate del2 = ClassB.MethodB;

            MyDelegate del = del1 + del2;
            del("Hello World");

            MyDelegate del3 = (string msg) => Console.WriteLine("Lambda ifoda ishlatilishi: " + msg);
            del += del3;
            del("Hello World");

            del = del - del2;
            del("Hello World");

            del -= del1;
            del("Hello World");

            Console.ReadKey();
        }
    }
    class ClassA
    {
        public static void MethodA(string message)
        {
            Console.WriteLine("ClassA.MethodA() metodi chaqirildi: " + message);
        }
    }
    class ClassB
    {
        public static void MethodB(string message)
        {
            Console.WriteLine("ClassB.MethodB() metodi chaqirildi: " + message);
        }
    }
}
```

**Natija:**

![](/files/-McjxFIHDWjKfdOdy9EZ)

Agar delegat qiymatni qaytaradigan bo'lsa, unda ko'p sonli delegat chaqirilganda oxirgi tayinlangan maqsad metodining qiymati qaytariladi.

```csharp
using System;
namespace Delegate
{
    public delegate int MyDelegate();

    class Program
    {
        static void Main(string[] args)
        {
            MyDelegate del1 = ClassA.MethodA;
            MyDelegate del2 = ClassB.MethodB;

            MyDelegate del = del1 + del2;
            Console.WriteLine(del()); //Ekranga 200 chiqadi

            Console.ReadKey();
        }
    }
    class ClassA
    {
        public static int MethodA()
        {
            return 100;
        }
    }
    class ClassB
    {
        public static int MethodB()
        {
            return 200;
        }
    }
}
```

***Umumiy delegat***

Umumiy delegatni delegat bilan bir xil tarzda aniqlash mumkin, lekin umumiy turdagi parametrlardan yoki qaytish turidan foydalangan holda. Maqsadli metodni o'rnatganingizda umumiy tur ko'rsatilishi kerak.

Masalan, int va string parametrlari uchun ishlatiladigan quyidagi umumiy delegatni ko'rib chiqamiz:

```csharp
using System;
namespace Delegate
{
    public delegate T add<T>(T param1, T param2);

    class Program
    {
        static void Main(string[] args)
        {
            add<int> sum = Sum;
            Console.WriteLine(sum(10, 20));

            add<string> con = Concat;
            Console.WriteLine(con("Hello ", "World!!"));

            Console.ReadKey();
        }
        public static int Sum(int val1, int val2)
        {
            return val1 + val2;
        }
        public static string Concat(string str1, string str2)
        {
            return str1 + str2;
        }
    }
}
```

**Natija:**

![](/files/-McjxFIJ68qlaVnlGG5t)


# Func delegati

Nodirbek Abdulaxadov

*Ko'p hollarda maxsus delegatlarni qo'lda belgilashga hojat qolmasligi uchun C# tarkibiga umumiy delegat turlari **Func** va **Action** kiritilgan.*

**Func** bu - System nomlar fazosiga kiritilgan umumiy delegatdir va u parametrlari bo'lmagan metodni kapsulaga soladi va parametr bilan ko'rsatilgan turdagi qiymatni qaytaradi. Bunda nol yoki undan ortiq kirish parametrlari va bitta chiqish parametri mavjud hisoblanib, oxirgi parametr har doim chiqish parametri sifatida bo'ladi. **Func** delegati parametrlari **<>** (burchakli qavs)lar ichida ko'rsatiladi.

Bitta kirish va chiqish parametriga ega **Func** delegatining umumiy ko'rinishi:

![](/files/-Md3PGxObkgS-yOU9mIa)

Misol:

```csharp
using System;

namespace Delegates
{
    class Program
    {
        static void Main(string[] args)
        {
            //delegatga metod tayinlash
            Func<int, bool> add = IsOdd;

            //son kiritish
            int number = int.Parse(Console.ReadLine());

            //delegatni ishlatish va natijani o'zlashtirish
            bool result = add(number);

            //natijani ekranga chiqarish
            Console.WriteLine($"{number} soni toqligi: {result}");

            Console.ReadKey();
        }

        //sonni toqlikka tekshiruvchi metod
        static bool IsOdd(int a)
        {
            return a % 2 == 1;
        }
    }
}
```

Natija:

![](/files/-Md3VlmapZT_sjPjbmOX)

Ikkita kirish va chiqish parametriga ega **Func** delegatining umumiy ko'rinishi:

![](/files/-Md3Qq5vHoAhC0W-c_0o)

Misol:

```csharp
using System;

namespace Delegates
{
    class Program
    {
        static void Main(string[] args)
        {
            //delegatga metod tayinlash
            Func<int, int, int> add = Summ;

            //sonlarni kiritish
            int number1 = int.Parse(Console.ReadLine());
            int number2 = int.Parse(Console.ReadLine());

            //delegatni ishlatish va natijani o'zlashtirish
            int result = add(number1, number2);

            //natijani ekranga chiqarish
            Console.WriteLine($"{number1} + {number2} = {result}");

            Console.ReadLine();
        }

        //Ikkita sonni yig'indisini qaytaruvchi metod
        static int Summ(int a, int b)
        {
            return a + b;
        }
    }
}
```

Natija:

![](/files/-Md3VlmbfOO0VxgkFYDg)

Yuqoridagi misollardan tashqari **Func** delegati maksimal 16 tagacha kirish parametrlarini qabul qilishi mumkin:

![](/files/-Md3c-ZZb7fHRGdZV3KH)

***Func** delegatining anonim metod bilan qo'llanishi:*

```csharp
Func<int> getRandomNumber = delegate()
                            {
                                Random rnd = new Random();
                                return rnd.Next(1, 100);
                            };
```

***Func** delegatining lyambida ifoda bilan qo'llanishi:*

```csharp
    Func<int> getRandomNumber = () => new Random().Next(1, 100);
//yoki
    Func<int, int, int>  Sum  = (x, y) => x + y;
```


# Action delegati

Nodirbek Abdulaxadov

**Action** delegati bu - [**Func**](https://docs.dot-net.uz/c-.net/basic/yuqori-daraja/delegatlar/func-delegati) kabi System nomlar fazosi tarkibiga kiruvchi umumiy delegatdir. **Action** delegati tuzilish jihatidan **Func** delegatiga o'xshash, lekin **Action** delegatida hech qanday parametr qaytarilmaydi. Shuning uchun **Action** delegati void tipli metodlar bilan ishlatiladi.

Masalan, quyidagi delegat int qiymatini ekranga chiqaradi:

```csharp
using System;

namespace Delegates
{
    class Program
    {
        public delegate void Print(int val);

        static void ConsolePrint(int i)
        {
            Console.WriteLine(i);
            Console.WriteLine("Print delegati yordamida ekranga chiqarildi");
        }

        static void Main(string[] args)
        {
            Print del_print = ConsolePrint;
            del_print(10);

            Console.ReadKey();
        }
    }
}
```

Natija:

![](/files/-MdDnt3q9HHqDaCcnKGo)

Endi xuddi shu metodni **Action** delegati yordamida ishlatib ko'ramiz:

```csharp
using System;

namespace Delegates
{
    class Program
    {
        static void ConsolePrint(int i)
        {
            Console.WriteLine(i);
            Console.WriteLine("Action delegati yordamida ekranga chiqarildi");
        }

        static void Main(string[] args)
        {
            Action<int> act_print = ConsolePrint;
            act_print(101);

            Console.ReadKey();
        }
    }
}
```

Natija:

![](/files/-MdDnt3swVATadqrlVQy)

Shu joyiga kelganda kallamni ichida qisqa tutashuv bo'lib simi tegib ketdi shekilli bir qiziq savol keb qoldi:

*Hali action delegati bilan, hali boshqa delegat bilan ishlatayotgan metodni o'ziga hech e'tibor berdingizmi? ConsolePrint metodining vazifasi nima? ConsolePrint metodini chaqirsam u baraka topkur Console.WriteLine metodini chaqiryapti. Ha qovun ConsolePrint ni ovora qilmasdan, to'g'ridan to'g'ri Console.WriteLine ga murojaat qilsam bo'lmaydimi?*

Xullas, yuz marta savol bergandan bir marta sinab ko'rgan yaxshi:

```csharp
using System;

namespace Delegates
{
    public delegate void Print(string i);
    public class Func3Example
    {
        public static void Main()
        {          
            Action<int> print = Console.WriteLine;
            print(12);

            Print del_print = Console.WriteLine;
            del_print("Xullas, bunaqasiyam ishlorakan ;)");

            Console.ReadKey();
        }
    }
}
```

Natija:

![](/files/-MdDnt3tAacLRZq4JoZa)

**Action** delegatini new kalit so'zi yordamida ham e'lon qilish mumkin:

```csharp
Action<int> print = new Action<int>(Console.WriteLine);
```

{% hint style="info" %}
**Action** delegati 16 tagacha har xil turdagi kirish parametrlarini qabul qilishi mumkin.
{% endhint %}

**Action** delagatining anonim metod bilan qo'llanishi:

```csharp
static void Main(string[] args)
{
    Action<int> printActionDel = delegate(int i)
                                {
                                    Console.WriteLine(i);
                                };

    printActionDel(10);
}
```

**Action** delegatining lyambda ifoda bilan qo'llanishi:

```csharp
static void Main(string[] args)
{
    Action<int> printActionDel = i => Console.WriteLine(i);

    printActionDel(10);
}
```

{% hint style="success" %}
**Action va Func delegatlarining afzalliklari**

* Delegatlarni aniqlash oson va tez.
* Kodni qisqa qiladi.
* Ilova davomida mos keladigan tip.
  {% endhint %}

***Shunday qilib, Action delegati tiplari bilan qiymat qaytarmaydigan har qanday metoddan foydalanishingiz mumkin.***


# Predicate delegati

Nodirbek Abdulaxadov

**Predicate** delegati bu - [**Func**](https://docs.dot-net.uz/c-.net/basic/yuqori-daraja/delegatlar/func-delegati) va [**Action**](https://docs.dot-net.uz/c-.net/basic/yuqori-daraja/delegatlar/action-delegati) kabi System nomlar fazosi tarkibiga kiruvchi umumiy delegatdir. U ma'lum bir qoidalar(shartlar) to'plamini o'z ichiga olgan metodni ifodalaydi va berilgan parametrni ushbu qoidalarga mos kelishini tekshiradi. **Predicate** delegati bitta kirish parametri hamda bool qiymatidagi bitta chiqish parametriga ega.

**Predicate** delegatining umumiy ko'rinishi:

![](/files/-MefGKFRzJtvqfUwov0L)

U quyidagi ko'rinishda e'lon qilinadi:

```csharp
  public delegate bool Predicate<in T>(T obj);
```

Quyidagi misolda: sonni tub ekanini tekshiruvchi metod yordamida **Predicate** qo'llab 2 dan 50 gacha bo'lgan oraliqdagi tub sonlarni ekranga chiqarish dasturini ko'ramiz:

```csharp
using System;

namespace Delegates
{
    class Program
    {
        static void Main(string[] args)
        {
            Predicate<int> predicate = IsPrime;

            for(int i=2; i<50; i++)
            {
                if(predicate(i)) Console.Write(i + " ");
            }
            Console.ReadKey();
        }

        static bool IsPrime(int n)
        {
            for(int i=2; i<=Math.Sqrt(n); i++)
            {
                if (n % i == 0) return false;
            }
            return true;
        }
    }
}
```

Natija:

![](/files/-MefQcbKi7JXWBNlRYDr)

Boshqa delegat turlari singari **Predicate** dan har qanday metod, anonim metod yoki lambda ifodasi bilan ham foydalanish mumkin.

Yuqoridagi masalaning anonim metod yordamidagi yechimi:

```csharp
    Predicate<int> predicate = delegate (int n)
    {
        for (int i = 2; i <= Math.Sqrt(n); i++)
        {
            if (n % i == 0) return false;
        }
        return true;
    };
```

Yuqoridagi masalaning lambda ifoda yordamidagi yechimi:

```csharp
    Predicate<int> predicate = (n=>
    {
        for (int i = 2; i <= Math.Sqrt(n); i++)
        {
            if (n % i == 0) return false;
        }
        return true;
    });
```


# Anonim metodlar

Nodirbek Abdulaxadov

*Yuqoridagi* [*Func*](https://docs.dot-net.uz/c-.net/basic/yuqori-daraja/delegatlar/func-delegati)*,* [*Action*](https://docs.dot-net.uz/c-.net/basic/yuqori-daraja/delegatlar/action-delegati) *va* [*Predicate*](https://docs.dot-net.uz/c-.net/basic/yuqori-daraja/delegatlar/predicate-delegati) *mavzularida ushbu delegatlarning anonim metod bilan qo'llanishini ko'rdik, lekin anonim metod qanday ekanligi haqida endi gaplashamiz.*&#xD83D;�

Nomidan ko'rinib turibdiki, **Anonim metod** - bu ismsiz metod. U metod bo'lsa, delegatlar mavzusida nima qilyapti degan savol tug'ilishi mumkin. Buning sababi shundaki, **Anonim metod** delegat tushunchasi bilan chambarchas bog'liq va delegatlarni chaqirish uchun ishlatiladi.

{% hint style="info" %}
Qisqacha qilib aytganda metodlarni nima deb nomlashni bilmasdan nom qidirgan paytingizda: *"keling endi shu metodni benom qoldiramiz"* deb yordamga keladi.
{% endhint %}

**Anonim metod** umumiy ko'rinishi:

![](/files/-Mesn_j47IZcgG9r7DiY)

{% hint style="success" %}
**Anonim metoddan foydalanish uchun quyidagi qadamlarni bajarish yetarli:**

* **Delegat e'lon qilish**
* **Delegatdan obyekt hosil qilish**
* ***delegate*****&#x20;kalit so'zi yordamida hosil qilingan obyektga mos nomsiz metod yozish**
* **delegatdan foydalanish**
  {% endhint %}

Misol:

```csharp
using System;

namespace Delegates
{
    class Program
    {
        //delegat e'lon qilish
        public delegate void Print(string s);
        static void Main(string[] args)
        {
            //delegatdan obyekt hosil qilib unga anonim metod tayinlash
            Print print;
            print = delegate (string str)
            {
                Console.WriteLine($"Hello {str}");
            };

            //delegatni chaqirish
            print("DOT-NET.UZ");

            Console.ReadKey();
        }
    }
}

//Chiquvchi:
//  Hello DOT-NET.UZ
```

**Anonim metod**lar ichida global o'zgaruvchilardan ham foydalanish mumkin. Quyidagi misolda biror sonning ko'rsatilgan darajasini hisoblovchi dastur ko'rsatilgan(anonim metod ichida 'a' global holatda, 'n' esa 'N' nomi bilan parametr sifatida ishlatilgan):

```csharp
using System;

namespace Delegates
{
    class Program
    {
        //delegat e'lon qilish
        public delegate int Degree(int i);
        static void Main(string[] args)
        {
            //o'zgaruvchilarni kiritish
            Console.Write("Son kiriting: ");
            int a = int.Parse(Console.ReadLine());
            Console.Write("Darajani kiriting: ");
            int n = int.Parse(Console.ReadLine());

            //delegatdan obyekt hosil qilib unga anonim metod tayinlash
            Degree d = delegate (int N)
            {
                return (int)Math.Pow(a, N);
            };

            //delegatni chaqirish
            Console.WriteLine($"\n{a} sonining {n}-darajasi: {d(n)}");

            Console.ReadKey();
        }
    }
}
```

Natija:

![](/files/-MegfrXPv8spC0b0vLvV)

{% hint style="danger" %}
**Anonim metod cheklovlari:**

* **Anonim metod** goto, break va continue o'tish operatorlarini o'z ichiga olmaydi
* **Anonim metod** out va ref parametrlarini ishlata olmaydi
* **Anonim metod** operatorning chap tomonida ishlatilmaydi
  {% endhint %}

**delegate** operatoridan foydalanishda parametrlarni tashlab ketish ham mumkin. Bunday holatda siz ixtiyoriy parametrlarni yuborish imkoniyatiga ega bo'lasiz:

```csharp
Action SayHello = delegate { Console.WriteLine("Hello!"); };
    SayHello();

Action<int, double, bool, string> introduce = delegate { Console.WriteLine("This method can be called with any parameters!"); };
    introduce(42, 2.7, 2>4, "Hello");
```

C# 9.0 dan boshlab siz **Anonim metod**larni static holatda e'lon qilishingiz mumkin:

```csharp
Func<int, int, double> degree = static delegate (int a, int b)
    {
        return Math.Pow(a, b);
    };
degree(2, 3);
```

Shuningdek **Anonim metod**lar Event Handler sifatida ham ishlatilishi mumkin:

```csharp
saveButton.Click += delegate(Object o, EventArgs e)
{ 
    //some code for saving
    System.Windows.Forms.MessageBox.Show("Save Successfully!"); 
};
```


# Hodisalar


# Extension metodlar

Sarvarbek Mumtozbekov

Extension metodlar oldindan aniqlangan tiplarga yangi metodlarni qo’shish imkoniyatini beradi. Bunday metodlar juda foydali bo’ladi agar bizda klass kodlarini o’zgartirishga imkoniyatimiz bo’lmasa. Yoki bo’lmasa voris olish imkoniyatimiz bo’lmasa, misol uchun klass *sealed* modifikatori bilan aniqlangan bo’lsa. Misol uchun biz string tipiga yangi metod qo’shmoqchimiz:

```csharp
int i = s.DigitsCount();
Console.WriteLine(i);

public static class StringExtension
{
    public static int DigitsCount(this string str)
    {
        int x = str. Count(c => Char.IsDigit(c));
        return x;
    }
}
```

Extension metod tuzish uchun oldin static klass yaratib olish kerak, aynan shu klassda extension metod yoziladi. Bizning misolda bu **StringExtension**. Bu klassga static metod yaratiladi. Bizning misolda bu **DigitsCount**. Bu metodning vazifasi satrdagi raqamlar sonini aniqlash. Umuman olganda extension metod bu oddiy static metod, faqat u birinchi parametr sifatida quyidagi ko’rinishida parametr yoziladi: `this tip_nomi patametr_nomi`, bizning holatda bu `this string str`. Bizning extension metodimiz string tipi uchun bo’lgani sababli biz string tipini ishlatamiz.

Endi bu metodni xohlagan satrimizga ishlatimiz mumkin:

```csharp
int i=”nimadir123”.DigitsCount();
```

Birinchi parametrni berish ham shart emas, birinchi parametr sifatida satrni o’zini oladi. Agar qo’shimcha parametr qo’shish kerak bo’lsa ikinchi, uchinchi parametr sifatida ketma-ket qo’shib yozilaveradi:

```csharp
public static ExtMethod(this int i, int x, int y){ … };
int x  =1; x.ExtMethod(1,2);
```


# Stream I/O

Abdumannon Shamsiyev

Bilamizki hozirgi kunda kompyuter va texnologiyalar jadal suratlarda rivojlanib bormoqda. Deyarli har kuni texnologiya olamida yangidan yangi o’zgarishlar, texnologiyalar, interactive dasturiy mahsulotlar yaratilmoqda. Shuni bilishingizni istardimki, bularning barchasining zamirida “Axborot” degan tushuncha bor. Axborot tushunchasiga ta’rif berish yoki uni to’loqonli tushuntirib berish mushkul masala. Shu sababli hamma axborotga nisbatan o’zining hissiyotlari orqali tushuncha oladi. Shu sabab axborot tushunchasini umumiy ifodalashimiz mumkin. Axborot deb insonning borliq bilan ta’sirlashishi(qarashga qarab tabiatning insonga yoki insonning tabiatga) va uni hissiyotlari bilan his qila olish qobiliyati orqali olgan qarashlariga aytiladi. Misol:

Kichkinalik vaqtingizda hali olov nimaligini bilmagan vaqtingizda qo’lingiz yoki biror tana a’zoingiz bilan olovga yaqinlashib ko’rgan vaqtingizni eslang. Aynan o’sha lahzada siz borliq va uning elementi - olov bilan ta’sirlashgansiz. Va shu vaqtda siz taxminan borliqda quyidagicha axborotlarni olgansiz:

* Olovning issiq bo’lishi;
* Kuchli olov insonga nisbatan salbiy ta’sir ko’rsatishi(kuydirishi);
* Olovni aql bilan ishlatsa inson faoiliyatida katta o’rin egallashi

kabi axborotlarni tanangiz va miyya faoliyatingiz orqali his qilgansiz. Va miyya bu ma’lumotlarni keyingi safar olov bilan qayta ta’sirlanish uchun tajriba ilmi sifatida saqlab qo’ygan. Shu sababdan ham biz olov bilan ehtiyotkor bo’lishga o’rganganmiz.

Aslida axborot mana shu, ya’ni Axborot – insonning ta’biat bilan ta’sirlashuvi demakdir. Va bu jarayonga "contex" ni yana qaytarmoqchiman. Ya’ni olov bilan sizning ta’sirlashuv jarayoningizga. Sizning ta’na a’zoingiz olovga ya’qinlashgan vaqtda nimani his qilasiz?

Albatta aytish mumkinki, Issiqlik. Ammo uni ko’zingiz bilan ko’rmaysiz. Shunchaki uni his qilasiz. Bu hissiyot esa ta’na a’zoingizning olovga ya’qinlashgan qismida joylashgan hujayralarning signallar hosil qilishi bilan sodir bo’ladi. Hujayralar ham siz bilan birgalikda tabiat bilan ta’sirlashada va signallar chiqaradi. Bu signallar esa nerv tomirlari orqali miyyaga boradi. Va miyya o’sha tana a’zoingizni himoya qilishga buyruq beradi. Qo’polroq qilib tushuntirganda umumiy jarayon shunaqa kechadi. Bu yerda e’tibor berishingizni so’ragan bo’lar edim, ya’ni nerv tomirlari signallarni miyyaga olib o’tish jarayoniga. Bu jarayonda signallar ayni olov ta’sirida bo’lgan hujayralarda hosil bo’ladi, yig’iladi va miyyaga uzatiladi. Mana shu uzatish jarayonini stream deya olamiz. Ya’ni Streamda ham axborot manbai va u uzatiladigan joylar mavjud bo’ladi. Va axborot stream bo’ylab uzatilib turadi. Vaqt o’tishi bilan stream ishini tugatgach u axborot manbai va u yuborilayotgan joy o’rtasida bog'lanish(connection) uziladi. Huddi tana a’zoimizni olovdan olib qochganda tinchlanganimiz kabi stream egallab turgan hajm yo’qotiladi. To’g’ri yuqorida yozganlarim tushunishga qiyin va juda murakkablashib ketgan bo’lishi mumkin. Ammo shu mavzuimiz ning asosi hisoblanadi.

Endi Texnik jihatdan stream larning ishlatilishini kuzatamiz. Demak stream lar ikki 2 qismdan iborat bo’ladi. Ya’ni axborot manbai va bu axborotni qabul qiluvchilar. Axborot manbai bo’lib hozirgi kundagi juda ko’plab qurilmalarni misol qilishimiz mumkin. Misol uchun wifi bilan ishlaydigan sichqoncha, televizor pulti va hokazolar. Qabul qiluvchilar esa mos ravishda kompyuter, TV. Ular o’rtasidagi almashayotgan ma’lumot esa axborot. U har xil ko’rinishda bo’lishi mumkin. Misol uchun 0 va 1 lar ko’rinishida(digital), analog elektr signallari yoki insonning tanasida kechuvchi signallar yoki bo’lmasa yorug’lik kabilar. Umuman olgan da streamning tushunchasi shunaqa.

Endi streamlarni dasturlash da qanday foydalanilishi ko’rib chiqamiz. Bu jarayonni C# dasturlash tilida .Net SDK sidan foydalangan holda amalga oshiramiz. Quyida ko’rib turganingiz .NET dagi System.Stream class. Bu class ning modeli yuqorida aytib o’tgan mulohazalarimiz asosida tuzilgan.

![](https://user-images.githubusercontent.com/91861166/223753297-cfd64236-f175-4eea-9003-d553a4b632a3.png)

Yuqoridagi Stream klassi va uning ichidagi barcha method va propertylarni ko’rishingiz mumkin. Bu yerda avval boshida aytib o’tgan mulohazalar dasturchiga oson bo’lguncha abstractionga aylantirilgan. Ammo e’tibor bilan bu klassni o’rganishga harakat qilsak avval boshida aytilgan mulohazalar implememtation qilinganini ko’rishimiz mumkin. Va yana shuni aytishimiz kerakki bu Stream faqat 0 va 1 ko’rinishidagi axborotlar bilan ishlaydi. Sabibi bilamizki bu yerda Stream axborotini qabul qiluvchi qurilma Kompyuter. Kompyuter esa faqat 0 va 1 ko’rinishidagi raqamli signallarni tushunadi. Endi bu method va propertylarning ba’zilari bilan tanishib chiqamiz.

* Length – bu stream o’zida olib ketayotgan axborotning hajmi demakdir.
* Position - bu stream dan ma’lumot o’qilayotganda yoki yozilayotganda aynan nechinchi byte ni yozayotganiga qarab belgilanadigan qiymat.
* CanRead – bu stream o’qiyotgan manbaning xususiyatlari va kelib chiqish shakliga qarab o’sha manbadan ma’lumot o’qish mumkin yoki mumkin emasligini ifodalaydi.
* CanSeek – bu stream o’qiyotgan manbaning xususiyatlari va kelib chiqish shakliga qarab o’sha manbadan o’qilayotgan ma’lumot bo’ylab ma’lumotlar ustida “Sakrash” yoki “O’tish” funksiyasini bajara olish mumkinligi yoki mumkin emasligini ifodalaydi.
* CanWrite – bu stream yozilayotgan yoki ma’lumot yuborilayotgan manbaning xususiyatlari va kelib chiqish shakliga qarab o’sha manbaga ma’lumot o’tkazish yoki yozish mumkin yoki mumkin emasligini ifodalaydi.
* Close – bu streamni ma’lumot olinayotgan va ma’lumot uzatilayotgan manbalar uchun faoliyatini yopadi. Ya’ni stream kompyuter xotirasidan butunlay o’chirib yuborilmaydi. Shunchaki keyinchalik o’chirilib yuborilish uchun priotite ni o’zgartiradi. Bu amaldan keyin streamdan ma’lumot olib ham ma’lumot uzatib ham bo’lmay qoladi
* Dispose – bu streamni ma’lumotlari bilan birgalikda xotiradan bo’shatish amali
* Flush – bu streamning bufferini tozalaydi. Buffer haqida esa keyingi mavzularda gaplashamiz.
* Read – bu stream olib kelayotgan ma’lumotning o’lchamidan bir birlik olishni anglatadi. Bizning holatda esa ma’lumotning birligini o’qib oladi.
* Write – bu streamga 1 birlik ma’lumotni yozadi va u axborotni qabul qiluvchi manbaga uzatiladi. System.Stream bu C# dagi eng kichik tushuncha. Deyarli Barcha I/O operationlarda Streamning o’rni katta. Streamga aloqador I/O operationni bajarishga yo‘naltirilgan klasslar asosiga yuqorida o’rgangan Sytem.Stream klassini asos qilib oladi. Misol uchun C#(.NET) da tayyorlab qo’yilgan quyidagi klass larni keltishimiz mumkin:
* InputStream
* OutputStream
* Console
* FileStream
* StreamReader
* TextReader
* BufferStream
* MemoryStream

va hokazolar.

Shunday qilib streamlar haqida o’rganishimiz kerak bo’lgan boshlang'ich ma’lumotlar shular edi.


# StreamWriter

Mamataliyev Diyorbek

Assalomu alaykum. C# da yozilgan dastur natijasini nafaqat Console oynasiga, biror matnli faylga ham yozib qo'yish imkoniyati mavjud. Buning uchun `System.IO` nomlar makoniga tegishli bo'lgan **StreamWriter** sinfidan foydalanish juda qulay. Ishonavering, buni o'rganish ham oson. Demak boshladik.

**StreamWriter** sinfidan foydalanish uchun eng avvalo `System.IO` nomlar makonini chaqiramiz. So'ng fayl nomini ko'rsatgan holda **StreamWriter** sinfidan obyekt olamiz. Masalan mana bunday:

```csharp
using System;
using System.IO;
class Program
  {
    static void Main(string[] args)
      {
         StreamWriter fayl1 = new StreamWriter("c://papka1/sonlar.txt");
      }
  }
```

Yuqoridagi kodimizda fayl1 - obyekt nomi, endi sonlar.txt fayliga shu nom bilan murojaat qilamiz. Qavs ichidagi nom esa sizga tanish, bu biz yozmoqchi bo'lgan faylning to'liq nomi. Bizning holatda fayl c diskda papka1 nomli papkada joylashgan.

{% hint style="info" %}
**ESLAB QOLING!** fayl nomi ko'rsatilayotganda mavjud bo'lmagan fayl ko'rsatilsa dastur o'zi ko'rsatilgan manzilda huddi shu nomda yangi fayl ochadi.

Agar to'liq nomi avvaldan mavjud bo'lgan fayl bilan aynan bir xil fayl ko'rsatilsa dastur ishlaganda fayl ichidagi yozuvlar to'la o'chirilib, yangitdan yozish boshlanadi.

Agar fayl mavjud bo'lmagan papka ichida ko'rsatilsa, dastur ishga tushmaydi. Bu holatda kompilyator `System.IO.DirectoryNotFoundException` nomli xatolik oynasini ekranga chiqaradi
{% endhint %}

Shuningdek, fayl manzilini ko'rsatishda faqatgina fayl nomini yozish ham mumkin:

```csharp
StreamWriter fayl1 = new StreamWriter("sonlar.txt");
```

Bu holatda dasturingiz fayllari joylashgan **bin** nomli papka ichida yangi fayl ochiladi.

Yangi faylni ochdik, endi unga qanday yozamiz? Sizga eng oson va to'g'ri yo'nalish: Avvalgi dasturlaringizda Console oynasiga ma'lumotni chop etish uchun foydalanilgan `Console.Write`va `Console.WriteLine` funksiyalaridagi `Console` so'zi o'rniga **StreamWriter**dan olingan obyekt nomini yozsangiz bas. Misol tariqasida c diskning o'zida yangi fayl ochib, unga 1 dan 10 gacha sonlarni yozib ko'ramiz:

```csharp
using System;
using System.IO;
class Program
{
  static void Main(string[] args)
  {
    StreamWriter new_file = new StreamWriter("c:/new file.txt");
    for (int i = 1; i < 11; i++)
        new_file.WriteLine(i);
    new_file.Close();
    Console.WriteLine("Sonlar faylga yozildi");
  }
}
```

{% hint style="info" %}
**BU MUHIM!** *StreamWriter* sinfi orqali ochilgan faylga yozib bo'lingach, albatta Close() funksiyasi orqali faylni yopish kerak. Aks holda fayldagi ma'lumotlar saqlanmaydi. Agar dasturda ochilgan faylni Close() orqali yopmay turib dasturdan chiqilsa, fayl ichidagi barcha ma'lumotlar o'chib ketadi.
{% endhint %}

Yangi faylga matn yozilishini o'zingiz ko'rish uchun yuqoridagi dastur kodini ishlatib ko'ring.

Yana bir foydali ma'lumot: Faylli oqim(StreamWriter)dan foydalanib ma'lumotlarni chop etish matnli oqim(Console)dan ko'ra ancha tez ishlaydi. Bu sizga ko'p ma'lumotlar chop etish kerak bo'lgan masalalarda ancha qo'l keladi.

{% hint style="info" %}
**StreamWriter**dan foydalanib nafaqat **txt** kengaytmali, yana **doc**, **docx**, **pdf**, **xls**, **xlsx**, **ppt** kengaytmali fayllarga ham yozish imkoniyati mavjud.
{% endhint %}

Demak, yuqorida keltirilgan misoldagi *new file.txt* nomi o'rniga *new file.doc*, *new file.ppt* kabi boshqa nomlar yozishimiz ham mumkin ekan. Natijada matn boshqa turdagi matnli faylga yoziladi. Boshqa kengaytmali fayllarga yozib ko'rish sizga vazifa bo'lib qoladi.

E'tiboringiz uchun rahmat.


# StreamReader

Mamataliyev Diyorbek

Biz matnli faylga ma'lumot yozish uchun **StreamWriter**dan foydalandik. Avvaldan yozilgan ma'lumotni o'qish uchun esa **StreamReader** sinfidan foydalanamiz. **StreamReader** sinfi **System.IO** nomlar makonida joylashgan.

**StreamReader**dan foydalanish uchun ham avval biror fayl nomini ko'rsatgan holda obyekt olamiz:

```csharp
using System;
using System.IO;
class Program
{
    static void Main(string[] args)
    {
        StreamReader fayltxt = new StreamReader("d:/fayl.txt");
        StreamReader fayldoc = new StreamReader("d:/hujjatlar/hujjat.doc");
        StreamReader fayldocx = new StreamReader("d:/f.docx");
        StreamReader faylxlsx = new StreamReader("c:/f.xlsx");
        StreamReader faylpdf = new StreamReader("f.pdf");
    }
}
```

{% hint style="info" %}
**Yodda tuting!** **StreamReader**da ko'rsatilgan fayl avvaldan ko'rsatilgan manzilda aynan shu nomda mavjud bo'lishi kerak. Aks holda, dastur ishga tushmaydi. Mavjud bo'lmagan faylga murojaat qilinganda kompilyator `System.IO.FileNotFoundExeption` nomli xatolik oynasini ekranga chiqaradi. Agar fayl biror papka ichida ko'rsatilgan bo'lsayu, bunday nomda papka mavjud bo'lmasa, `System.IO.DirectoryNotFoundExeption` xatoligi yuz beradi.
{% endhint %}

Agar disk nomini yozmay fayl nomining o'zini yozish orqali murojaat qilinsa, kompilyator bu faylni dastur joylashgan \*\*\*bin\*\*\* papkasi ichidan qidiradi.

Keling, endi kichik bir dastur tuzib ko'ramiz. Bizning dasturimiz fayldagi birinchi qatordagi ma'lumotlarni o'qib, Console oynasiga chiqarib bersin:

```csharp
using System;
using System.IO;
class Program
{
    static void Main(string[] args)
    {
        StreamReader f = new StreamReader("c:/f.txt");
        string matn = f.ReadLine();
        Console.WriteLine(matn);
        
        Console.ReadKey();
    }
}
```

Yuqoridagi kodni ishlatib ko'rishdan avval c diskda f.txt nomli fayl ochib, unga ixtiyoriy matn yozing va saqlang. Keyin dasturni ishlatganingizda u siz yozgan matnning birinchi qatorini Console ga chiqarganiga guvoh bo'lasiz.

Agar faqat bir qator matnni emas, fayldagi barcha ma'lumotni birdaniga o'qib olmoqchi bo'lsakchi? Buning uchun ReadLine() o'rniga ReadToEnd() metodidan foydalanamiz:

```csharp
using System;
using System.IO;
class Program
{
    static void Main(string[] args)
    {
        StreamReader f = new StreamReader("c:/f.txt");
        string matn = f.ReadToEnd();
        Console.WriteLine(matn);
        
        Console.ReadKey();
    }
}
```

Natijada f.txt faylidagi barcha ma'lumotlar Console oynasiga chiqariladi.


# MemoryStream

Sariboyev Jasurbek

Xo'sh do'stlar mana o'tgan darslarda turli xildagi fayllarga ma'lumotlarni yozishni, o'qishni va saqlashni ko'rdingiz, keling endi bizdagi ma'lumotlarni fayllarga emas balki kompyuterimiz xotirasiga saqlashni ko'rib chiqamiz.

MemoryStream ham "Stream" sinf(class)laridan biri bo'lib, bu sinf(class) ham System.IO nomlar makoni(namespace)da joylashgan. Uning koddagi ko'rinishi(syntax) MemoryStream ni undan obyekt olib ishlatamiz :

```csharp
MemoryStream memStream = new MemoryStream();
```

Nomidan ham ko'rinib turibdiki, u to'g'ridan-to'g'ri xotiradagi ma'lumotlar bilan shug'ullanadi, ya'ni ma'lumotlarimizni kompyuterning tezkor xotirasi(RAM)da vaqtinchalik saqlab turadi. Uning ustunligi tezkorligidadir. Agar biz ma'lumotlarga ko'plab murojaat qiladigan bo'lsak MemoryStream dan foydalanish afzaldir chunki, MemoryStreamdagi baytlar diskda emas, balki xotirada saqlanadi. Keling bir misolda ko'rib chiqamiz. O'zimiz bilgan StreamWriter orqali oddiy matn fayliga "Salom, Dunyo !!!" deb yozamiz va uning barcha baytlarni byte array orqali o'qiymiz. Keyin biz ushbu saqlangan baytlar bilan MemoryStream yaratamiz va MemoryStream dan barcha satrlarni o'qiy oladigan o'zimiz bilgan StreamReader yaratamiz.

```csharp
using System;
using System.IO;
using System.Text;

class MemStream
{
    static void Main()
    {
        StreamWriter writer = new StreamWriter("biror.txt");
        writer.WriteLine("Salom, Dunyo !!!");
        writer.Close();
        
        byte[] bytesAll = File.ReadAllBytes("biror.txt");

        MemoryStream memoryStream = new MemoryStream(bytesAll);

        StreamReader stream = new StreamReader(memoryStream);  
     
                string line;
                while ((line = stream.ReadLine()) != null)
                    Console.WriteLine(line);
            stream.Close();
        
        memoryStream.Close();
    }
}
```

Output:`Salom, Dunyo !!!`

Har bir stream ni tugatish uchun "close" ning o'rniga "using" kalit so'zi bilan blokdan foydalanishingiz mumkin (1=2).

1.

```csharp
MemoryStream memoryStream = new MemoryStream();
...... 

memoryStream.Close();
```

2.

```csharp
using(MemoryStream memoryStream = new MemoryStream())
{
......
}
```

{% hint style="info" %}
MUHIM! MemoryStream dan har doim ham foydalanish tavsiya berilmaydi, chunki :

1. Ma'lumotlar hajmi katta bo'lsa RAM ga sig'may qolishi mumkin;
2. MemoryStreamda saqlagan ma'lumotlar dastur yopilganda yoki kompyuter o'chiib yoqilishi kabi holatlarda yo'qolib qolishi ya'ni xotiradan o'chib ketishi mumkin.
   {% endhint %}


# File va Directory


# FileInfo

Nodirbek Abdulaxadov

FileInfo sinfi - fayllarni yaratish, nusxalash, o'chirish, ko'chirish va ochish uchun xususiyatlar va metodlarni taqdim etadi. Shuningdek, [FileStream](https://docs.microsoft.com/en-us/dotnet/api/system.io.filestream?view=net-5.0) obyektlarini yaratishda yordam beradi.

**FileInfo xususiyatlari:**

| Directory      | Fayl joylashgan katalog nomini qaytaradi         |
| -------------- | ------------------------------------------------ |
| DirectoryName  | Fayl joylashgan to’liq katalog nomini qaytaradi  |
| Exists         | Fayl mavjudligini tekshiradi                     |
| Extension      | Fayl turini(kengaytmasini) qaytaradi             |
| FullName       | Faylning to’liq manzilini qaytaradi              |
| IsReadOnly     | Fayl faqat o’qish uchunligini tekshiradi         |
| CreationTime   | Fayl yaratilgan vaqtini qaytaradi                |
| LastAccessTime | Fayl ishlatilgan oxirgi vaqtni qaytaradi         |
| LastWriteTime  | Faylning oxirgi o’zgartirilgan vaqtini qaytaradi |
| Length         | Fayl hajmini qaytaradi (baytlarda)               |
| Name           | Fayl nomini qayatardi                            |

**FileInfo metodlari:**

| AppendText | FileInfo ushbu nusxasi tomonidan taqdim etilgan faylga matn qo'shadigan StreamWriter yaratadi. |
| ---------- | ---------------------------------------------------------------------------------------------- |
| CopyTo     | Mavjud faylning ustiga yozishni taqiqlab, mavjud faylni yangi faylga ko'chiradi.               |
| Create     | Fayl yaratadi                                                                                  |
| CreateText | Yangi matnli faylni yozadigan StreamWriter-ni yaratadi.                                        |
| Delete     | Belgilangan faylni o'chiradi.                                                                  |
| MoveTo     | Belgilangan faylni yangi joyga ko'chiradi va yangi fayl nomini ko'rsatish imkoniyatini beradi. |
| Open       | Belgilangan FileMode-da ochadi.                                                                |
| OpenRead   | Faqat o'qish uchun FileStream yaratadi.                                                        |
| OpenText   | Mavjud matnli fayldan o'qiydigan UTF8 kodlash bilan StreamReader yaratadi.                     |
| OpenWrite  | Faqat yozish uchun FileStream yaratadi.                                                        |

*FileInfo xususiyatlardan foydalanish:*

```csharp
using System;
using System.IO;

namespace FileInfo_examples
{
    class Program
    {
        static void Main(string[] args)
        {
            //faylga yo'l
            string path = @"C:\Users\user\Desktop\test.txt";

            //FileInfo sinfidan yangi obyekt hosil qilish
            FileInfo fileInfo = new FileInfo(path);

            //Exist yordamida fayl mavjudligini tekshirish
            if (fileInfo.Exists)
            {
                //fayl xususiyatlarini chiqarish
                Console.WriteLine($"Fayl joylashgan katalog: \t{fileInfo.Directory}");
                Console.WriteLine($"Fayl kengaytmasi: \t{fileInfo.Extension}");
                Console.WriteLine($"Faylning to'liq nomi: \t{fileInfo.FullName}");
                Console.WriteLine($"Yaratilgan vaqti: \t{fileInfo.CreationTime}");
                Console.WriteLine($"Hajmi: \t{fileInfo.Length} bayt");
            }

            Console.ReadKey();
        }
    }
}
```

![](/files/-M_-2mtZv3Yw4H08CnVo)

*FileInfo metodlaridan foydalanish:*

```csharp
using System;
using System.IO;
namespace FileInfo_Examples
{
    class Test
    {
        public static void Main()
        {
            string path = Path.GetTempFileName();
            var fi1 = new FileInfo(path);

            // Create a file to write to.
            using (StreamWriter sw = fi1.CreateText())
            {
                sw.WriteLine("Hello");
                sw.WriteLine("And");
                sw.WriteLine("Welcome");
            }

            // Open the file to read from.
            using (StreamReader sr = fi1.OpenText())
            {
                var s = "";
                while ((s = sr.ReadLine()) != null)
                {
                    Console.WriteLine(s);
                }
            }

            try
            {
                string path2 = Path.GetTempFileName();
                var fi2 = new FileInfo(path2);

                // Ensure that the target does not exist.
                fi2.Delete();

                // Copy the file.
                fi1.CopyTo(path2);
                Console.WriteLine($"{path} was copied to {path2}.");

                // Delete the newly created file.
                fi2.Delete();
                Console.WriteLine($"{path2} was successfully deleted.");
            }
            catch (Exception e)
            {
                Console.WriteLine($"The process failed: {e.ToString()}");
            }
            Console.ReadKey();
        }
    }
}
```

![](/files/-M_-3XZeb7Ns_DIg8gJz)

**Izohlar:**

Fayllarni ko'chirish, nomini o'zgartirish, yaratish, ochish, o'chirish va qo'shib qo'yish kabi odatiy operatsiyalar uchun FileInfo sinfidan foydalaning.

Agar bitta faylda bir nechta operatsiyalarni bajarayotgan bo'lsangiz , [File](https://docs.microsoft.com/en-us/dotnet/api/system.io.file?view=net-5.0) sinfining tegishli statik metodlari o'rniga [FileInfo](https://docs.microsoft.com/en-us/dotnet/api/system.io.fileinfo?view=net-5.0) instansiya metodlaridan foydalanish samaraliroq bo'lishi mumkin , chunki xavfsizlikni tekshirish har doim ham talab qilinmaydi.

**Code source**👉[FileInfo xususiyatlari va metodlari qo’llanishiga doir misollar](https://github.com/Nodirbek-Abdulaxadov/FileInfo-examples)


# DirectoryInfo

Nodirbek Abdulaxadov

C# dasturlash tilida kataloglar bilan ishlash uchun System.IO nomlar fazosida aniqlangan 2 ta sinf mavjud: **Directory** va **DirectoryInfo**

**Directory** sinfi - kataloglarni yaratish, nusxalash, ko'chirish yoki o'chirish kabi ishlar uchun bir qator statik metodlarni taqdim etadi.

**DirectoryInfo** sinfi - kataloglarni yaratish, nusxalash, ko'chirish yoki o'chirish kabi odatiy ishlar uchun ishlatiladi. Ko'p jihatdan u Katalogga o'xshaydi. DirectoryInfo sinfida statik metodlar mavjud emas va ularni faqat moslashtirilgan obyektlarda ishlatish mumkin. Ushbu sinf meros qilib olinishi mumkin emas.


# MultiThread va Parallel dasturlash


# Asinxron dasturlash

Ravshan Sodiqov

Asinxron dasturlash – bu asosiy dastur jarayonini bloklamagan holda, bajarilayotgan vazifalarni alohida bloklarga olish imkonini beradi. Dastur ishlashi foydalanuvchi so’rovlarini qayta ishlash, ma’lumotlar bazalariga va tarmoq resurlariga kirish kabi nisbatan ko’proq vaqt talab etiladigan vazifalardan iborat bo’lganda, asosiy oqimni bloklab qo’ymaslik uchun asinxron usullardan foydalaniladi.

![](https://user-images.githubusercontent.com/91861166/150674299-01336b58-30c8-414f-89e5-0d31a2d9e618.png)

Masalan, hajm va matn jihatdan nisbatan kattaroq fayldan ma’lumotlarni o’qish dasturini qaraymiz:

Sinxron usul:

```csharp
private string ReadFile(string file)
{
    string content = string.Empty;
    using (StreamReader reader = new StreamReader(file))
    {
        content = reader.ReadToEnd();
    }
    return content;
}
```

Bunda **ReadFile()** funksiyasi toki fayldan ma’lumotlar o’qib bo’lingunga qadar asosiy dastur jarayoni bloklanib turadi. Chunki biz ma’lumotni o’qishda sinxron usuldan foydalandik, bu esa juda noqulay jarayon va dastur ishlash vaqtini ham sezilarli darajada oshib yuboradi. Endi ushbu muammolarni hal etish uchun dasturning asosiy jarayonini bloklamagan holda asinxron usuldan foydalanamiz:

Asinxron usul:

```csharp
private async Task<string> ReadFileAsync(string file)
{
    string content = string.Empty;

    using (StreamReader reader = new StreamReader(file))
    {
        content = await reader.ReadToEndAsync();
    }

    return content;
}
```

Endi ushbu holatda ma’lumotlarni o’qish uchun **ReadToEndAsync()** metodidan foydalandik va dastur jarayoni ham bloklab qo’yilmadi.

E’tibor bering: Biz asinxron usuldan foydalanish uchun **Task**, **async**, va **await** kabi yangi kalit so’zlardan foydalandik va ishlash jarayoni asinxron tarzda ekanligini anglatish uchun **ReadFileAsync** nomidan foydalandik (o’zgartirmaslik ham mumkin edi, bu dasturchining ixtiyorida, prinsipial jihatdan aslida bu kerak emas). **ReadToEndAsync()** metodi esa asinxron tarzda ishlaydigan maxsus metod.

Yodda tuting: Asinxron usul quyidagi xususiyatlarga ega:

• Umumiy jarayon bir yoki bir nechta asinxron metodlardan iborat bo’ladi.

• Jarayon ichidagi har bir asinxron metodlar oldidan await kalit so’zi ishlatiladi.

• Umumiy jarayon bitta bo’lsa ham asinxron metodni o’z ichiga olsa, uning nomi oldidan async kalit so’zi ishlatiladi.

• Jarayonning qiymat qaytarish turi ham bir necha usulda aniqlanadi:

o void

o Task

o Task

o ValueTask<>

Asinxron usullar doimgidek bir yoki bir nechta parametrlar qabul qilishi mumkin, ammo, parametrlarni **ref** va **out** modifikatorlari bilan aniqlab bo’lmaydi. Jarayon nomi oldidan **async** kalit so’zini ishlatish ham dasturni avtomatik tarzda asinxron usulga o’tkazmaydi, balki, bunda bir nechta asinxron metodlardan foydalanish imkonini yaratadi. Yuqoridagi **ReadToEndAsync()** metodi kabi .NET Core olamida asinxron tarzda ishlovchi metodlar mavjud va ular sinxron usulda ishlovchi metodlardan farqli ravishda *Async* qo’shimchasi bilan tugaydi. Biz har bir asinxron metodni chaqirishdan oldin **await** kalit so’zini ishlatishimiz mumkin. Endi yuqorida berilgan fayldagi ma’lumotlarni asinxron tarzda o’qish jarayonini Main metodi ichida qanday boshlash kerak ekanligini qaraymiz:

```csharp
namespace AsynAwaitDemo
{
    class Program
    {
        static async Task<string> ReadFileAsync(string file)
        {
            string content = string.Empty;

            using (StreamReader reader = new StreamReader(file))
            {
                content = await reader.ReadToEndAsync();
            }

            return content;
        }

        static async void ContentToConsole()
        {
            string readFileTask = await ReadFileAsync("c:\\temp\\file.txt");

            Console.WriteLine("Fayldagi ma'lumotlar:" + readFileTask);
        }

        static void Main(string[] args)
        {
            Task task = new Task(ContentToConsole);
            task.Start();
            task.Wait();
            Console.ReadLine();
        }
    }
}
```

Ushbu holatda Main metodi ichida **ContentToConsole()** jarayonini boshlash uchun Task obyektidan foydalandik va parametr sifatida ushbu nom berildi. **ContentToConsole()** o’z navbatida asinxron tarzda ishlovchi **ReadFileAsync()** metodini o’z ichiga olgan va ushbu metod qaytargan qiymatni Console ga chiqarishi bilan jarayon yakunlanadi. Biz asosiy dastur qismini bloklamagan holda nisbatan katta hajmdagi fayllardan ma’lumotlarni o’qish jarayoniga erishdik va bu dastur foydalanuvchisiga ham noqulaylik keltirib chiqarmaydi.

Asinxron dasturlashga bir hayotiy misol: siz yaxshi biladigan Telegram ilovasida ham asinxron dasturlashdan foydalanilgan. Shuning uchun Telegramga hajmi nisbatan kattaroq faylni yuklayotgan paytingizda bir vaqtning o'zida boshqa chatlardagi xabarlarni o'qish, yoki telegramda boshqa jarayonlarni amalga oshirish imkoni bor. Bu bir nechta jarayonlar asinxron tarzda ishlayveradi. Agar telegram dasturida asinxron emas, sinxron dasturlashdan foydalanilganida toki faylni to'la yuklab bo'lgunicha interfeys bloklanib, boshqa hech qanday amal bajarishning imkoni bo'lmasdi.

Asinxron metodlar ko’pchilik holatlarda veb ilovalarda yangi foydalanuvchi yaratish so’rovi yuborilganda yoki ma’lumotlar bazasidan tegishli ma’lumotlarni o’qish jarayonidan ancha qo’l keladi va bu foydalanuvchi interfeysi bilan bog’liq muammolarni ham keltirib chiqarmaydi.


# XML Document bilan ishlash

Nodirbek Abdulaxadov

**XML** (e**X**tensible **M**arkup **L**anguage) - kengaytirilgan markerlash tili degan ma'noni anglatadi va SGML (**S**tandard **G**eneralized **M**arkup **L**anguage) standart umumlashtirilgan markerlash tilidan olingan matnga asoslangan markerlash tilidir.

{% hint style="success" %}
**XML** teglari HTML teglari kabi ma'lumotlarni ko'rsatish uchun ishlatilmaydi. Aksincha, **XML** - ma'lumotlarni saqlash va tartibga solish uchun ishlatiladi. Yaqin kelajakda **XML** HTML o'rnini bosmaydi, lekin u HTML ning ko'plab muvaffaqiyatli xususiyatlarini qo'llash orqali yangi imkoniyatlarni ochib beradi.
{% endhint %}

**XML** hujjatlar bilan ishlash uchun C# dasturlash tilida [**System.Xml**](https://docs.microsoft.com/en-us/dotnet/api/system.xml?view=net-5.0) nomlar fazosidagi asosan quyidagi sinflardan foydalaniladi:

* [**XmlDocument**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmldocument?view=net-5.0)
* [**XmlConvert**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlconvert?view=net-5.0)
* [**XmlNode**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlnode?view=net-5.0)
* [**XmlNodeList**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlnodelist?view=net-5.0)
* [**XmlScheme**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlscheme?view=net-5.0)
* [**XmlReader**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlreader?view=net-5.0)
* [**XmlTextReader**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmltextreader?view=net-5.0)
* [**XmlWriter**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlwriter?view=net-5.0)
* [**XmlTextWriter**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmltextwriter?view=net-5.0)

**Keling endi gapni cho'zmasdan amaliyotga o'tamiz. Quyida biz XML hujjat hosil qilishning bir nechta usullarini ko'rib chiqamiz.**

*Jarayonda biz Talaba modelidan tuzilgan Talabalar jadvalidan foydalanamiz:*

```csharp
public class Talaba
    {
        public int Id { get; set; }
        public string Ism { get; set; }
        public string Familiya { get; set; }
        public string TelNomer { get; set; }
    }
```

## 1. [**XmlDocument**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmldocument?view=net-5.0) va [**XmlNode**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlnode?view=net-5.0) sinflari yordamida:

**XmlDocument** sinfidan yangi obyekt hosil qilamiz:

```csharp
XmlDocument document = new XmlDocument();
```

**XmlNode** sinfi orqali Xml hujjat parametrlarini hosil qilamiz va uni AppendChild metodi yordamida document ga qo'shamiz:

```csharp
XmlNode xnode = document.CreateXmlDeclaration("1.0", "UTF-8", null);
document.AppendChild(xnode);
```

{% hint style="info" %}
Xml da yangi element hosil qilish XmlNode sinfining CreateElement metodi, elementga qiymat berish uchun esa CreateTextNode metodidan foydalanamiz.
{% endhint %}

Talabalar nomli bosh elementni yaratamiz va uni documentga qo'shamiz:

```csharp
XmlNode talabalar = document.CreateElement("Talabar");
document.AppendChild(talabalar);
```

Endi Talaba modelining xususiyatlarini element shaklida tashkil qilgan Talaba nomli element hosil qilamiz:

```csharp
XmlNode talaba = document.CreateElement("Talaba");
talabalar.AppendChild(talaba);

XmlNode id = document.CreateElement("Id");
id.AppendChild(document.CreateTextNode("1"));
talaba.AppendChild(id);

XmlNode ism = document.CreateElement("Ism");
ism.AppendChild(document.CreateTextNode("Nodirbek"));
talaba.AppendChild(ism);

XmlNode familiya = document.CreateElement("Familiya");
familiya.AppendChild(document.CreateTextNode("Abdulaxadov"));
talaba.AppendChild(familiya);

XmlNode nomer = document.CreateElement("TelNomer");
nomer.AppendChild(document.CreateTextNode("+998901234567"));
talaba.AppendChild(nomer);
```

Yaratgan Xml hujjatimizni saqlaymiz:

```csharp
document.Save("Talabalar.xml");
```

**Natijamiz:**

![](/files/k7nv6eAdapyxyv8bbI9T)

## 2. [**XmlWriter**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmlwriter?view=net-5.0) sinfi yordamida:

{% hint style="info" %}
XmlWriter sinfining metodlari:

* Create - Yangi hujjat obyektini yaratish
* WriteStartDocument - Yangi hujjat yozishni boshlash
* WriteStartElement - Yangi element ochish
* WriteValue - Element qiymatini kiritish
* WriteEndElement - elementni yopish
* WriteEndDocument - hujjatni yopish
* Flush - hujjatni saqlash
  {% endhint %}

XmlWriter sinfining metodlaridan va yuqoridagi model va ketma-ketlikdan foydalanib yangi Talabalar.xml nomli hujjat hosil qilamiz.

**XmlWriter** sinfidan yangi obyekt hosil qilish uchun dastlab uning sozlamalarini hosil qilish kerak bo'ladi:

```csharp
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
```

XmlWriter obyektini Talabalar.xml fayli nomi va yuqoridagi settings bilan hosil qilamiz:

```csharp
XmlWriter writer = XmlWriter.Create("Talabalar.xml", settings);
```

Talaba modelining xususiyatlarini kiritib, hujjatimizni hosil qilamiz:

```csharp
writer.WriteStartDocument();
writer.WriteStartElement("Talabalar");

writer.WriteStartElement("Talaba");

writer.WriteStartElement("Id");
writer.WriteValue("1");
writer.WriteEndElement();

writer.WriteStartElement("Ism");
writer.WriteValue("Baxtiyor");
writer.WriteEndElement();

writer.WriteStartElement("Familiya");
writer.WriteValue("Murodov");
writer.WriteEndElement();

writer.WriteStartElement("TelNomer");
writer.WriteValue("+998901234567");
writer.WriteEndElement();

writer.WriteEndDocument();
writer.Flush();
```

## 3. **XML** hujjat hosil qilish uchun C# dasturlash tilida [**System.Xml.Linq**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.linq?view=net-5.0) nomlar fazosidagi [**XElement**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.linq.xelement?view=net-5.0) sinfidan ham foydalansak bo'ladi:

Va nihoyat men yoqtirgan usulga ham yetib keldik 😄!

{% hint style="success" %}
**XElement** sinfi yordamida XML hujjat hosil qilish birmuncha oson va tushunarli. Har bir element va uning ichidagi elementlar shajaraga o'xshab joylashadi.
{% endhint %}

```csharp
XElement talabalar =
    new XElement("Talabalar",
        new XElement("Talaba",
            new XElement("Id", "1"),
            new XElement("Ism", "Baxtiyor"),
            new XElement("Familiya", "Murodov"),
            new XElement("Tel_nomer", "+998901234567")));

    talabalar.Save("Talabalar.xml");
```

## 4. **XML** hujjatni JSON fayllar kabi [Serialize](https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/serialization/) qilish orqali ham yaratishimiz mumkin. Buning uchun bizga [**System.Xml.Serialization**](https://docs.microsoft.com/en-us/dotnet/api/system.xml.serialization?view=net-5.0) nomlar fazosidagi sinflar kerak bo'ladi.

Dastlab Talaba modelimizga \[Serializable] attributini qo'shishimiz kerak bo'ladi:

```csharp
[Serializable]
public class Talaba
    {
        public int Id { get; set; }
        public string Ism { get; set; }
        public string Familiya { get; set; }
        public string TelNomer { get; set; }
    }
```

Yangi Talaba obyektini xususiyatlari bilan yaratamiz va Talabalar listiga qo'shamiz:

```csharp
Talaba talaba = new Talaba
        {
            Id = 1,
            Ism = "Baxtiyor",
            Familiya = "Murodov",
            TelNomer = "+998901234567"
        };
        
List<Talaba> talabalar = new List<Talaba>();
talabalar.Add(talaba);
```

Obyektimizni serialize qilamiz va TextWriter yordamida Talabalar.xml nomi bilan saqlaymiz:

```csharp
XmlSerializer serializer = new XmlSerializer(typeof(List<Talaba>));
TextWriter twriter = new StreamWriter("Talabalar.xml");

serializer.Serialize(twriter, talabalar);
twriter.Close();
```

**Natijamiz:**

![](/files/bBQcOZ4WTyGRmHlVlLLx)

*Qachondir davomi bor yana ;)*


# LINQ asoslari

Nodirbek Abdulaxadov

**LINQ** (Language-Integrated Query) - bu ma'lumot manbasidan so’rov olish uchun oddiy va qulay til. Ma'lumotlar manbayi sifatida - IEnumerable interfeysini (masalan, standart to'plamlar, massivlar) amalga oshiradigan obyekt, DataSet, XML hujjati bo'lishi mumkin. Ammo manba turidan qat'iy nazar, LINQ ma'lumotni olish uchun barchasi uchun bir xil usulni qo'llashga imkon beradi.

**Qisqacha qilib aytganda** **LINQ** - *kodni ixchamlashtirish va oson o'qish imkoniyatini beradi va undan turli xil ma'lumot manbalari uchun so'rovlarda foydalanish mumkin.*

**LINQ** ning bir nechta turi mavjud:

* **LINQ to Objects** : Massivlar va to'plamlar bilan ishlash uchun ishlatiladi
* **LINQ to Entities** : Entity Framework texnologiyasi orqali ma'lumotlar bazalariga kirishda foydalaniladi
* **LINQ dan Sql** : MS SQL Server-da ma'lumotlarga kirish texnologiyasi
* **LINQ to XML** : XML fayllari bilan ishlashda ishlatiladi
* **LINQ to DataSet** : DataSet obyekti bilan ishlashda foydalaniladi
* **Parallel LINQ (PLINQ)** : parallel so'rovlarni bajarish uchun ishlatiladi

![](/files/-MZsuzm0dEZeo8hILOO8)

**LINQ** so'rovlari natijalarni obyekt sifatida qaytaradi. Bu sizga natijalar to'plamida obyektga yo'naltirilgan yondashuvni ishlatishga va natijalarning turli formatlarini obyektlarga aylantirish haqida tashvishlanmaslikka imkon beradi.

**LINQ-ning afzalliklari**

* **Tanish til:** Ishlab chiquvchilar ma'lumotlar manbalarining har bir turi yoki ma'lumotlar formati uchun yangi so'rovlar tilini o'rganishlari shart emas.
* **Kamroq kod yozish:** Bu an'anaviy yondoshuv bilan taqqoslaganda yoziladigan kod miqdorini ancha kamaytiradi.
* **Tushunarli kod:** LINQ kodni yanada tushunarli qiladi, shuning uchun boshqa ishlab chiquvchilar uni osonlikcha tushunishlari va saqlab turishlari mumkin.
* **Bir nechta ma'lumot manbalarini so'rov qilishning standartlashtirilgan usuli:** Bir xil ma'lumot manbalariga so'rov yozish uchun bir xil LINQ sintaksisidan foydalanish mumkin.
* **So'rovlarning vaqt xavfsizligini** kompilyatsiya qilish: kompilyatsiya vaqtida obyektlarning turini tekshirishni ta'minlaydi.
* **IntelliSense-ni qo'llab-quvvatlash:** LINQ umumiy to'plamlar uchun IntelliSense-ni taqdim etadi.
* **Ma'lumotlarni shakllantirish:** Siz har xil shakldagi ma'lumotlarni olishingiz mumkin.

### **LINQ** dan foydalanish

LINQ dan foydalanish uchun bizga .Net Framework 3.5 va C# 3.0 kerak bo’ladi(foydalanish uchun minimum versiyalar).

**System** kutubxonasiga qo’shimcha ravishda **System.Linq** kutubxonasidan foydalanamiz.

***

**Misol:**

```csharp
using System;
using System.Linq;
namespace LINQ_operations
{
    class Program
    {
        static void Main(string[] args)
        {
            // Ma’lumotlar manbayi (massiv)
            string[] names = { "Bill", "Steve", "James", "Mohan" };
            // LINQ so’rovi 
            var myLinqQuery = from name in names
                              where name.Contains('a')
                              select name;
            // So’rovni ishlatish
            foreach (var name in myLinqQuery)
                Console.WriteLine(name + " ");
            Console.ReadKey();
            
            //some comment
        }
    }
}
```

**Natija:**

![](/files/-MZswzMmdUI5wLQ3Qr3N)

**Amaldagi LINQ metodlari ro'yxati**

* [**Select**](https://docs.dot-net.uz/c-.net/linq/select) : tanlangan qiymatlarning proektsiyasini belgilaydi
* [**Where**](https://docs.dot-net.uz/c-.net/linq/where) : tanlov filtrini belgilaydi
* [**OrderBy**](https://docs.dot-net.uz/c-.net/linq/orderby-va-orderbydescending) : elementlarni o'sish tartibida tartiblaydi
* [**OrderByDescending**](https://docs.dot-net.uz/c-.net/linq/orderby-va-orderbydescending) : elementlarni kamayish tartibida tartiblaydi
* [**ThenBy**](https://docs.dot-net.uz/c-.net/linq/thenby-va-thenbydescending) : elementlarni o'sish tartibida tartiblash uchun qo'shimcha shartlarni belgilaydi
* [**ThenByDescending**](https://docs.dot-net.uz/c-.net/linq/thenby-va-thenbydescending) : elementlarni kamayish tartibida tartiblash uchun qo'shimcha shartlarni belgilaydi
* [**Join**](https://docs.dot-net.uz/c-.net/linq/join-operatorlari) : ma'lum bir shart asosida ikkita to'plamni birlashtiradi
* **GroupBy** : elementlarni kalitlarga ko'ra guruhlaydi
* **ToLookup** : barcha elementlarni lug'atga qo'shgan holda elementlarni kalitlarga ko'ra guruhlaydi
* [**GroupJoin**](https://docs.dot-net.uz/c-.net/linq/join-operatorlari/group-join) : elementlarning ikkala to'plamini va kalitlarga ko'ra guruhlanishini amalga oshiradi
* [**Reverse**](https://docs.dot-net.uz/c-.net/linq/reverse) : elementlarni teskari tartibda tartiblaydi
* [**All**](https://docs.dot-net.uz/c-.net/linq/miqdor-operatorlari/all) : to'plamdagi barcha elementlarning ma'lum bir shartga javob berishini aniqlaydi
* [**Any**](https://docs.dot-net.uz/c-.net/linq/miqdor-operatorlari/any) : to'plamdagi kamida bitta elementning ma'lum bir shartga javob berishini aniqlaydi
* [**Contains**](https://docs.dot-net.uz/c-.net/linq/miqdor-operatorlari/contains) : to'plamda ma'lum bir element mavjudligini aniqlaydi
* [**Distinct**](https://docs.dot-net.uz/c-.net/linq/set-operatsiyasi/distinct) : to'plamdagi nusxalarni(bir xil elementlarni) olib tashlaydi
* [**Except**](https://docs.dot-net.uz/c-.net/linq/set-operatsiyasi/except) : ikkita to'plamning farqini, ya'ni faqat bitta to'plamda mavjud elementlarni qaytaradi
* [**Union**](https://docs.dot-net.uz/c-.net/linq/set-operatsiyasi/union) : ikkita bir xil to'plamlarni birlashtiradi
* [**Intersect**](https://docs.dot-net.uz/c-.net/linq/set-operatsiyasi/intersect) : ikki to'plamning kesishmasini, ya'ni ikkala to'plamda ham bo'lgan elementlarning kesishmasini qaytaradi
* **Count** : to'plamdagi ma'lum bir shartga javob beradigan elementlar sonini hisoblaydi
* **Sum** : to'plamdagi sonli qiymatlar yig'indisini hisoblaydi
* **Average** : to'plamdagi sonli qiymatlarning o'rtacha qiymatini hisoblaydi
* **Min** : minimal qiymatni topadi
* **Max** : maksimal qiymatni topadi
* [**Take**](https://docs.dot-net.uz/c-.net/linq/bolim-operatorlari/take) : ma'lum miqdordagi elementlarni tanlaydi
* [**Skip**](https://docs.dot-net.uz/c-.net/linq/bolim-operatorlari/skip) : ma'lum miqdordagi elementlarni o'tkazib yuboradi
* [**TakeWhile**](https://docs.dot-net.uz/c-.net/linq/bolim-operatorlari/takewhile) : agar shart to'g'ri bo'lsa, ketma-ketlik elementlari zanjirini qaytaradi
* [**SkipWhile**](https://docs.dot-net.uz/c-.net/linq/bolim-operatorlari/skipwhile) : ular berilgan shartni bajarishi sharti bilan elementlarni ketma-ketlikda o'tkazib yuboradi va keyin qolgan elementlarni qaytaradi
* **Concat** : ikkita to'plamni birlashtiradi
* **Zip** : ma'lum bir shartga muvofiq ikkita to'plamni birlashtiradi
* [**First**](https://docs.dot-net.uz/c-.net/linq/element-operatsiyalari/first-va-firstordefault) : to'plamdagi birinchi elementni tanlaydi
* [**FirstOrDefault**](https://docs.dot-net.uz/c-.net/linq/element-operatsiyalari/first-va-firstordefault) : to'plamdagi birinchi elementni tanlaydi yoki sukut bo'yicha qaytaradi
* [**Single**](https://docs.dot-net.uz/c-.net/linq/element-operatsiyalari/single-va-singleordefault) : to'plamning bitta elementini tanlaydi, agar to'plamda bir yoki bir nechta element bo'lsa, istisno hosil bo'ladi
* [**SingleOrDefault**](https://docs.dot-net.uz/c-.net/linq/element-operatsiyalari/single-va-singleordefault) : to'plamdagi birinchi elementni tanlaydi yoki sukut bo'yicha qaytaradi
* [**ElementAt**](https://docs.dot-net.uz/c-.net/linq/element-operatsiyalari/elementat) : ma'lum bir indeksda ketma-ketlik elementini tanlaydi
* **ElementAtOrDefault** : muayyan indeksda yig'ish elementini tanlaydi yoki indeks doiradan tashqarida bo'lsa, sukut bo'yicha qaytaradi
* [**Last**](https://docs.dot-net.uz/c-.net/linq/element-operatsiyalari/last-va-lastordefault) : to'plamdagi oxirgi elementni tanlaydi
* [**LastOrDefault**](https://docs.dot-net.uz/c-.net/linq/element-operatsiyalari/last-va-lastordefault) : to'plamdagi so'nggi elementni tanlaydi yoki sukut bo'yicha qaytaradi

[LINQ metodlarining qo’llanishiga doir misollar\*\*.\*\*](https://github.com/Nodirbek-Abdulaxadov/DOTNET.UZ/tree/main/LINQ-operations-master)\*\*\*\*


# Average

Jamshid Sodiqov

Average metodi to’plamdagi int tipidagi elementlarning o’rtacha qiymatini qaytaradi. Average metodi null, decimal, double yoki float qiymatini qaytaradi. Quyidagi misolda to'plamdagi barcha butun sonlarning o'rtacha qiymatini qaytaradigan Agerage metodini ishlashi ko'rsatilgan:

```
IList intList = new List>() { 10, 20, 30 };
var avg = intList.Average();
Console.WriteLine("Average: {0}", avg);
```

Siz o'rtacha qiymatni olmoqchi bo'lgan lambda ifodasi sifatida sinfning int, decimal, double yoki float propertylarini belgilashingiz mumkin. Quyidagi misolda murakkab turdagi Average metodinini ko'rsatadi:

```
IList studentList = new List>()
{ 
    new Student() { StudentID = 1, StudentName = "John", Age = 13} ,
    new Student() { StudentID = 2, StudentName = "Moin", Age = 21 } , 
    new Student() { StudentID = 3, StudentName = "Bill", Age = 18 } , 
    new Student() { StudentID = 4, StudentName = "Ram" , Age = 20} ,
    new Student() { StudentID = 5, StudentName = "Ron" , Age = 15 } 
};
var avgAge = studentList.Average(s => s.Age);
Console.WriteLine("Average Age of Student: {0}", avgAge);
```

**Output:**

**Average Of Student: 17.4**

{% hint style="info" %}
C# dasturlash tilida Average operatori query sintaksisida qo’llab quvvatlanmaydi!
{% endhint %}


# LINQ qanday ishlaydi?

Jasurbek Xasanboyev

LINQ ma'lumotlar bazasiga (data source)ga murojaatlar yuborish va ma'lumotlarni qayta ishlash uchun xizmat qiladi. LINQ so'rovlar (query) ma'lumotlar manbasi turlariga qarab bo'limlarga bo'linadi:

![](/files/-Mbz3sXZpdiyyhl9WQVU)

Misol tariqasida eng oddiy so'rov turini ko'rib chiqamiz:

```csharp
class LINQQueryExample // dot-net.uz uchun
{
    static void Main()
    {
        // Ma'lumotlarni to`plam shaklida shakllantirib olamiz
        int[] scores = new int[] { 97, 92, 81, 60 };

        // Query yozamiz
        IEnumerable<int> scoreQuery =
            from score in scores
            where score > 80
            select score;

        // Query ma'lumotlaridan foydalanamiz 
        foreach (int i in scoreQuery)
        {
            Console.Write(i + " ");
        }
    }
}
// Output: 97 92 81
```

> Tepadagi kodda LINQ so'rov yordamida to'plam elementlari orasidan 80 dan kattalaridan yangi to'plam hosil qilindi va ekranga chiqarildi ;)


# LINQ query yozish usullari

Suxrob Xayitmurodov

Kamina is back again baby!! :haha

Assalomu alaykum hurmatli yurtdoshlar. Galdagi mavzuyimizda **LINQ** da **query** yozish usullari ko'rib chiqamiz. C# tilida **query**larni yozishning 3 xil usullari mavjud. Har bir usulning o'ziga yarasha kerakli tomonlari mavjud:

1. Query Syntax
2. Method Syntax
3. Mixed Syntax (Query + Method)

Birinchisidan boshlaymiz: **Query Syntax** usuli har qanday murakkab querylani oson, tushunishga qulay va sodda ko'rinishga ega usul hisoblanadi. Bu usul ko'p hollarda SQL queryga juda o'xshab ketadi. Quyida siz ushbu usulning sintaksisini ko'rishingiz mumkin:

```csharp
from obj in dataSource
where condition
select obj
```

Ikkinchisidan davom ettiramiz: **Method Syntax** bugungi kunda eng mashhur usullardan hisoblanadi (serioz). Chunki ko'pgina murakkab vazifalarni ushbu usul bilan osonlikcha hal qilsa bo'ladi. Bu usul sintaksisi o'qishga juda oson hisoblanadi (ko'pchilik dasturchilar tomonidan tasdiqlangan). Lekin murakkab **query**lar uchun ushbu usulni **Query Syntax**ga nisbatan yozish birmuncha qiyin. Bu usulda **query** bir necha metodlar (albatta nuqta(.)) bilan aralashgan holda yoziladi. Quyida sintaksisini ko'rishingiz mumkin:

```csharp
DataSource.ConditionMethod().SelectionMethod()
```

Uchinchisi bilan tugatamiz: **Mixed Syntax**. Bu usul joriy usullar, **Query Syntax** va **Method Syntax**larning kombinatsiyasi desak adashmaymiz. Ushbu usul bilan **query**larni yozish bir muncha osonlashishi mumkin. Sintaksisi quyidagicha

```csharp
(from obj in dataSource
where condition
select obj).Method()
```

Agarda 10 daqiqa vaqtingizni diqqat bilan ushbu maqolaga sarflasangiz, demak siz hech qachon **query** yozish usullarida qiyinchiliklarga duch kelmaysiz!

```csharp
class LINQQueryExample // dot-net.uz uchun
{
    static void Main()
    {
        List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        var querySyntax = from obj in list
                          where obj > 2
                          select obj;
        foreach (var item in querySyntax)
        {
            Console.WriteLine(item);
        }
        Console.WriteLine("#____________#_____________#________________#");


        var methodSyntax = list.Where(obj => obj > 2);

        foreach (var item in methodSyntax)
        {
            Console.WriteLine(item);
        }
        Console.WriteLine("#____________#_____________#________________#");



        var mixedSyntax = (from obj in list
                           select obj).Max();

        Console.WriteLine("Max value: " + mixedSyntax);

    }
}
```




---

[Next Page](/llms-full.txt/1)

