Introducere in .NET
De ce C#? In primul rand, trebuie sa intelegem cum au evoluat limbajele de programare si de ce anumite limbaje nu sunt sustenabile pentru anumite aplicatii.
Motivul principal este legat de geriatria codului sursa. Ca o aplicatie sa fie profitabila pe termen lung trebuie sa poata fi intretinuta si extinsa. Lucrul acesta s-a dovedit a fi destul de greu cu limbaje de nivel jos cum ar fi limbajele de asamblare care puteau sa difere de la o arhitectura la alta. Peste acestea s-au construit limbaje de nivel inalt cum ar fi C care sa abstractizeze si sa usureze munca programatorilor de a scrie acelasi cod care sa ruleze pe sisteme hardware diferite insa si codul pentru aceste limbaje s-a dovedit a fi destul de greu de intretinut. Pe scurt, inca se crea mult cod care pentru diferite cazuri de utilizare era in mare acelasi, cum s-ar spune informal cod "copy-paste" sau cod boiler-plate.
Ulterior, au fost identificate diferite stiluri de programare care sa ajute programatorii a intretine cod mai bine micsorand codul sursa. Aceste stiluri de programare se numesc paradigme iar limbajele moderne precum C#, C++, Java, Go si Kotlin suporta mai multe paradigme in acelasi timp.
In limbajul C, de exemplu, suporta paradigma imperativa si procedurala, imperativa insemnand ca in codul sursa se specifica pas cu pas ce trebuie sa indeplineasca programul, iar procedural ca se folosesc apeluri de proceduri (functii) care sa indeplineasca un subset de pasi. Toate limbajele moderne suporta aceste paradigme. Ce nu suporta limbajul C este programarea orientata pe obiecte (Object-Oriented Programming) sau programare functionala (Functional Programming) spre deosebire fata de C#.
C# este un limbaj compilat la fel ca C insa acesta nu este compilat in cod masina pentru o anumita arhitectura de hardware ci intr-o reprezentare intermediara numita Common Intermediate Language (CIL) care poate fi interpretat de catre un mediu de rulare (runtime enviroment, sau pe scurt runtime) care aici este .NET. La rulare codul intermediare se transforma in cod masina nativ pentru arhitectura pe care ruleaza programul, asta inseamna ca o data scris si compilat codul poate fi rulat pe orice sistem hardware daca exista implementat runtime-ul pentru acesta.
Acest lucru face ca aplicatiile scrise in C# sa poata fi portate pe mai multe platforme. Aceasta abordare este similara ca in Java unde codul este compilat in Java byte-code is apoi rulat de catre JVM (Java Virtual Machine) care este echivalentul la .NET. Desi .NET ca runtime a fost creat doar pentru sistemul de operare Microsoft Windows la momentul actual, este disponibil si pentru alte sisteme de operare cum ar fi Linux si Android.
Aventajele de a avea un runtime sunt ca o data compilat codul se poate rula pe mai multe siteme (compile once run anywhere), iar acest lucru este un mare avantaj pentru a implementa aplicatii cross-platform, si faptul ca memoria poate fi gestionata in mod automat de acesta fara interventia programatorului. Practic runtime-ul se ocupa de alocare si dezalocare iar multe structuri de date sunt implicit pointeri fara sa fie vazute ca atare. Dezaventajul pe care il are este ca se presupune mai mult timp de procesare si memorie consumata pentru interpretarea codului intermediar.
Cu toate acestea, limbajele cu runtime mai au inca un avantaj care le face mult mai utile in pofida eficientei mai scazute, anume prin runtime se poate face reflexie. Reflexie inseamna ca se pot cere in mod dinamic in timpul rularii programului informatii despre structurile de date din program. Ba chiar mai mult, se pot crea in mod dinamic structuri de date fara declararea explicita de catre programator. Acest lucru se poate vedea cel mai bine in programarea sistemelor cloud, cel mai simplu lucru ce se poate face cu reflexie este sa fie mapate campuri dintr-un format text sau binar, cum ar fi un JSON, intr-o structura de date in mod automat camp cu camp.