Սովորում ենք C# | Կրճատ ներածություն .NET հարթակին
Tags: csharp, dotnet, beginners, armenian
Published: 2020-01-20 19:52:34


Ողջույն, գրառումների այս շարքում կիսվելու եմ C# ծրագրավորման լեզուն սովորելու իմ ուղով։ Քանի որ ծրագրավորման մեջ մասնագիտանալու համար բավարար չէ միայն լեզվի իմացությունը, հետագայում ձեռք կբերենք գրագետ ծրագրեր մշակելու համար անհրաժեշտ այլ գիտելիքներ, այդ թվում՝
* Օբյեկտ-կողմնորոշված ծրագրավորում (*object-oriented programming*)
* Տվյալների կառույցներ (*data structures*) և ալգորիթմեր
* Զուգահեռ ծրագրավորում (*concurrency*)

Քանի որ C# (արտասանվում է՝ "C Sharp") լեզվի հետ աշխատելու գործիքակազմը տրամադրում է .NET (արտասանվում է՝ "dot net") հարթակը, անհրաժեշտ է առաջին հերթին հասկանալ, թե ինչ է վերջինս իրենից ներկայացնում։ Գնացի՛նք 🏁 

### **Ի՞նչ է .NET-ը**

Ըստ Microsoft ընկերության բնութագրի, .NET-ը հանդիսանում է ծրագրերի մշակման հարթակ, որը հնարավորություն է ընձեռում տարբեր ծրագրավորման լեզուների միջոցով (C#, F#, Visual Basic, Python, C++/CLI) ստեղծել տարատեսակ հավելվածներ՝ 
* Web հավելվածներ (ASP.NET)
* Դասական Windows հավելվածներ (Windows Presentation Foundation)
* Android, iOS, Windows բջջային հավելվածներ (Xamarin)
* Windows 10 ՕՀ-ով օժտված համակարգիչների/պլանշետների, XBox, HoloLens, Internet of Things համակարգերի հավելվածներ/խաղեր (Universal Windows Platform)

Ծրագրավորման հնարավոր միջավայրերի բազմազանությունը պայմանավորված է նրանով, որ իրականում .NET անվան տակ գործում են հարթակի մի քանի տարբերակներ (*implementation*)`
* .NET Framework - .NET առաջին տարբերակը, որը նախատեսված է բացառապես Windows ՕՀ-ի հետ աշխատանքի համար
* .NET Core - 2016թ-ից ի վեր թողարկվող այս տարբերակը համատեղելի է Windows, macOS և Linux համակարգերի հետ
* Mono/Xamarin - Xamarin միջավայրի շարժիչը, որը համատեղելի է մի շարք բջջային ՕՀ-ների հետ (iOS, Android, tvOS, watchOS)

Բոլոր այս միջավայրերը միավորված են .NET Standard կոչվող փաստաթղթի միջոցով, որը սահմանում է .NET-ի ցանկացած տարբերակի համար անհրաժեշտ բազային ֆունկցիոնալությունը (պատրաստի կլասսերի գրադարանների կազմը)։

.NET հարթակի նշանակալի առանձնահատկությունն է ծրագրավորման լեզուների միջև փոխգործակցության հնարավորությունը (*language interoperability*), ինչը նշանակում է, որ միևնույն ծրագրի տարբեր մասեր կարող են մշակվել տարբեր լեզուներով։

### **Ինչպե՞ս է աշխատում .NET-ը**
.NET հարթակի "շարժիչը"՝ **Common Language Runtime (CLR)**-ը պատասխանատու է ծրագրային կոդի կատարման (*execution*), տիպերի համապատասխանության ստուգման (*type safety*) և այլ կարևոր խնդիրների լուծման համար (օր․՝ չօգտագործվող օբյեկտների ոչնչացում (*garbage collection*), զուգահեռ գործընթացների կարգավորում (*concurrency*)։ Նշված թեմաների հետ կառնչվենք հետագայում)։ 

Այժմ փորձենք հասկանալ, թե կոնկրետ ինչպես է մեր կողմից գրված C# կոդը վերածվում կատարվող ծրագրի։ .NET-ի հետ համատեղելի լեզուների դեպքում գործում է երկփուլ մեթոդ՝ 

1) Մեր կողմից գրված կոդը կոմպիլյացիայի մեթոդով թարգմանվում է .NET-ում գործող միջանկյալ լեզվի (**MSIL - Microsoft Intermediate Language** կամ **CIL - Common Intermediate Language**)
2) Այնուհետև ծրագիրը MSIL-ից JIT կոմպիլյացիայի մեթոդով թարգմանվում է մեքենայական լեզվի

> **Ի՞նչ է կոմպիլյացիան**
> Ծրագրավորման լեզուները բաժանվում են պայմանական մակարդակների, ինչքան ցածր է տվյալ լեզվի մակարդակն, այնքան այն կախված է պրոցեսորի առանձնահատկություններից (և դժվար ընթեռնելի է մարդկանց համար): Բարձր մակարդակի լեզուները (որոնցով սովորաբար աշխատում է ծրագրավորողների մեծ մասը) թույլ են տալիս օգտագործել նույն կոդը, անկախ պրոցեսորից։ 
Այս ճկունությունն ապահովելու համար օգտագործվում են միջանկյալ գործիքներ՝ կոմպիլյատորներ կամ ինտերպրետատորներ, որոնց աշխատանքի սկզբունքները հետևյալն են՝
* Կոմպիլյացիա (*compilation*՝ հավաքագրում) - կոդն ամբողջապես ընթերցվում է և թարգմանում ցածր մակարդակի լեզվի, որից հետո արտածվում է կատարվող (*executable*) ծրագիր,
* Ինտերպրետացիա (*interpretation*` թարգմանություն) - կոդն ընթերցվում է պնդում առ պնդում, և ամեն ընթերցված հրաման կատարվում է տեղում։

#### Քայլ առաջին

Այժմ կմանրամասնենք առաջին փուլում կատարվող ձևափոխությունը (C# → MSIL)։ Որպես օրինակ դիտարկենք պարզագույն ծրագրի կոդ՝

```c#
using System;
public static class Program {
    public static void Main() {
        Console.WriteLine("Բարև, Հայաստան");
    }
}
```
Տվյալ ծրագիրը կատարելիս էկրանին կարտածվի `Բարև, Հայաստան` արտահայտությունը։ Օգտագործված բոլոր հրամաններին (որոնք կոչվում են բանալի բառեր՝ *keyword*) մանրամասն կանդրադառնանք հետագայում․ դրանց կարճ բացատրությունները հետևյալն են՝ 
* `using System` - ներմուծել `System` կոչվող անվանացանկը 
* `public static class Program` - հայտարարել `Program` անունով [դաս](https://hy.wikipedia.org/wiki/%D4%B4%D5%A1%D5%BD_(%D5%AE%D6%80%D5%A1%D5%A3%D6%80%D5%A1%D5%BE%D5%B8%D6%80%D5%B8%D6%82%D5%B4)) ("կլասս")
* `public static void Main()` - հայտարարել `Main` անունով ֆունկցիա,
* `Console.WriteLine` - էկրանին արտածել փակագծերի մեջ տրված արժեքը/արտահայտությունը։

Վերոնշյալ կոդը կատարվող ծրագրի վերածելիս առաջին հերթին այն կոմպիլյացվում է՝ հատուկ ծրագրի (կոմպիլյատորի՝ *compiler*) միջոցով թարգմանվում է MSIL-ի։ 
> Կախված օգտագործվող .NET տարբերակից, կոպիլյատորը կարող է լինել տարբեր, օրինակ՝ դասական .NET Framework-ի դեպքում այն կոչվում է csc.exe (C-Sharp Compiler), իսկ .NET Core տարբերակն օգտագործում է ավելի նոր Roslyn-ը։

Մեր ծրագրի կոմպիլյացիայի արդյունքն ունի հետևյալ տեսքը (տվյալ պահին մի՛ փորձեք մանրամասն հասկանալ այս կոդը)՝
````
.class public auto ansi abstract sealed beforefieldinit Program
extends [System.Private.CoreLib]System.Object
{
    // Methods
    .method public hidebysig static
        void Main () cil managed
    {
        // Method begins at RVA 0x2050
        // Code size 13 (0xd)
        .maxstack 8
        IL_0000: nop
        IL_0001: ldstr "Բարև, Հայաստան"
        IL_0006: call void [System.Console]System.Console::WriteLine(string)
        IL_000b: nop
        IL_000c: ret
    } // end of method Program::Main
} // end of class Program
```
#### Քայլ երկրորդ

Տվյալ MSIL կոդը կարող է կատարվել .NET-ի հետ համատեղելի ցանկացած օպերացիոն համակարգով (**Operating System**) և պրոցեսորի կառուցվածքով (**CPU architecture**) համակարգչի միջոցով, բայց դրա համար անհրաժեշտ է այն թարգմանել տվյալ համակարգչի համար հասկանալի մեքենայական կոդի (տարբեր կառուցվածք ունեցող պրոցեսորների համար մեքենայական լեզուն տարբեր է)։ Այս նպատակով իրականացվում է միջանկյալ կոդի **JIT կոմպիլյացիա**, ինչն էլ հանդիսանում է .NET հարթակի վրա ծրագրի կատարման երկրորդ փուլը։
> **Ի՞նչ է JIT (Just-In-Time` տվյալ պահին) կոմպիլյացիան**
Ինչպես արդեն նշեցի, դասական կոմպիլյացիայի ժամանակ սկզբնական կոդն ընթերցվում է ամբողջովին և թարգմանվում է ավելի ցածր մակարդակի լեզվով գրված ծրագրի։ Ի տարբերություն դասականի, JIT կոմպիլյացիայի պարագայում կոդն ընթերցվում է ֆունկցիա առ ֆունկցիա, և տվյալ ֆունկցիան կոմպիլյացվում է միայն այն ժամանակ, երբ այն կանչվում է առաջին անգամ (հետագա կանչերը ուղղորդվում են արդեն իսկ թարգմանված տարբերակին, որը պահվում է հիշողության մեջ)։


Դեռևս այսքանը🏁
Հաջորդ գրառումներում կզինվենք անհրաժեշտ գործիքներով և կսկսենք գրել մեր առաջին C# ծրագրերը։ Շնորհակալ եմ ընթերցելու համար։

### **Օգտակար հղումներ**
* [C# → MSIL կոմպիլյացիայի օնլայն գործիք](sharplab.io)

Անգլերեն
* [A tour of C# - Microsoft.com](https://docs.microsoft.com/en-us/dotnet/csharp/tour-of-csharp/)
* [Understanding .NET Just-In-Time compilation - Telerik.com](https://www.telerik.com/blogs/understanding-net-just-in-time-compilation)

Ռուսերեն
* [Краткий обзор языка C# - Microsoft.com](https://docs.microsoft.com/ru-ru/dotnet/csharp/tour-of-csharp/)
* [Язык C# и платформа .NET Core](https://metanit.com/sharp/tutorial/1.1.php)