Nazwa języka powstała analogicznie jak nazwaC++. Operator ++ wjęzyku C (w C++ też) oznacza zwiększenie o jeden, więc C++ to więcej niż C. Autorzy C# wykorzystali podobny pomysł, gdzie symbol krzyżyka/kratki przypomina cztery połączone ze sobą operatory +. W muzyce dźwięk C♯ jest wyższy niż dźwięk C, może to sugerować, że język jest rozwinięciem C/C++[6].
Symbol♯ (krzyżyk) jest niedostępny na większości klawiatur, niektórych czcionkach iprzeglądarkach internetowych, dlatego zalecane jest używaniesymbolu kratki (#), który bardzo przypomina symbol muzyczny. Czasami tam gdzie ma to uzasadnienie np. w materiałach promocyjnych, Microsoft używa nazwy C♯ zamiast C#[7].
obiektowość z hierarchią o jednym elemencie nadrzędnym: podobnie jak w Javie, kod programu jest zbiorem klas. W C#, podobnie jak w Javie/Object Pascalu, hierarchia dziedziczenia opiera się na istnieniu jednej klasyObject (System.Object), która stanowi element nadrzędny tej hierarchii. W szczególności oznacza to, że również typy proste (int,double, itd.) są strukturami z właściwymi sobie metodami, np.inti=1;strings=i.ToString();
odśmiecanie pamięci: zarządzaniem pamięcią zajmuje się środowisko uruchomieniowe. Oznacza to, że nie ma potrzeby samodzielnego zajmowania się zwalnianiem pamięci po obiektach, które przestają być używane
refleksje i atrybuty klas: w czasie pracy programu istnieje możliwość analizy struktury kodu z poziomu tego kodu. Umożliwia to tworzenie wysoce uniwersalnych mechanizmów operujących na strukturze kodu nieznanej w czasie kompilacji. Mechanizm ten wykorzystywany jest m.in. w bibliotekachORM, narzędziach do analizy i weryfikacji kodu czy rozszerzeniachAOP. Mechanizm atrybutów został z C# zapożyczony do językaJava w wersji 1.5 (adnotacje), jakkolwiek samo Reflection API istniejące od pierwszego wydania języka stanowiło inspirację dla twórców C#
typy ogólne (generics – dostępne od wersji.NET 2.0): mechanizm zbliżony swoją ogólnością doszablonów w C++, jednak tu typ ogólny jest przenoszony domodułu binarnego i możliwy jest do wykorzystania bez konieczności posiadaniakodu źródłowego
dynamiczne tworzenie kodu: biblioteki.NET umożliwiają dynamiczne tworzenie kodu w czasie działania programu i włączanie go do kodu aktualnie wykonywanego. Możliwe jest zarówno dynamiczne tworzenie kodu wykonywalnego ze źródeł C# jak i tworzenie dynamicznych modułów w języku pośrednim (CIL).
bogata biblioteka klasBCL, umożliwiająca rozwijanie aplikacji konsolowych, okienkowych (System.Windows.Forms oraz WPF od .NET Framework 3.0), bazodanowych (ADO.NET), sieciowych (System.Net), w architekturze rozproszonej (WebServices) czy dynamicznych aplikacji internetowych (ASP.NET) oraz dynamiczne treści multimedialne (Silverlight).
W C#, podobnie jak w C stosuje się dwa rodzajekomentarzy:
// to komentarz jednoliniowy, czyli wszystkiego, co znajduje się za nim, kompilator nie bierze pod uwagę.
Komentarz wielowierszowy zaczyna się od/* a kończy*/. Kompilator nie bierze pod uwagę tego, co znajduje się pomiędzy.
Jeśli komentarz zaczyna się od/// lub/**, to jest to komentarz, w którym umieszcza się dokumentację do kodu.
Kopiec zaimplementowany przy pomocy szablonu klasy:
publicclassKopiec<T>{privateT[]tablica;// konstruktorpublicKopiec(T[]tablica){...}// wstawianie nowego elementu do kopcapublicvoidWstaw(Telem){...}}
słowo kluczoweyield.
typy częściowe – umożliwiają rozbicie klasy, struktury lub interfejsu do wielu plików źródłowych. Klasa częściowa wymaga użycia słowa kluczowegopartial.
metody anonimowe – pozwalają na tworzenie funkcji „w miejscu”. Funkcje takie umożliwiają związanie kodu funkcji bezpośrednio z instancją delegata. Oznacza to, że te funkcje nie mają nazwy i mogą być wywołane jedynie przez wywołanie delegata.
typy Nullable – to typ prosty, który łączy wartości swojego typu podstawowego z dodatkowym oznaczeniem braku wartości (null). Typy te są tworzone przez połączenie nazwy typu prostego ze znakiem ‘?’ np. int?, float?. Głównym zastosowaniem tych typów jest współpraca z bazami danych. Reprezentują one wartości uzyskane zbazy danych, uwzględniając możliwość nie istnienia danej wartości w bazie.
pattern matching - umożliwia sprawdzanie, czy zmienna jest danego typu i, jeśli tak, przypisanie tej wartości do nowej zmiennej typu docelowego. Możliwe jest również dołączanie dodatkowych warunków za pomocą słowa kluczowegowhen
Jest obsługiwany przez środowisko Visual Studio 2019, a jego kompilator jest częścią platformy .NET Core 3.x[10][11].
Elementy członkowskie tylko do odczytu
Domyślne metody interfejsu
Ulepszenia dopasowania wzorca:
Przełączanie wyrażeń
Wzorce właściwości
Wzorce krotki
Wzorce pozycyjne
Używanie deklaracji
Statyczne funkcje lokalne
Indeksy i zakresy
varzdanie=newstring[]{// indeks od początku indeks od końca"Ala",// 0 ^7"ma",// 1 ^6"kota",// 2 ^5"a",// 3 ^4"kot",// 4 ^3"ma",// 5 ^2"Alę.",// 6 ^1};// 7 (lub words.Length) ^0Console.WriteLine($"Ostatnie słowo w zdaniu to {zdanie[^1]}");// program wypisze "Alę."
Autorzy bibliotek mogą teraz określać priorytety rozdzielczości przeciążeń, co pozwala na bardziej precyzyjne kontrolowanie, która wersja metody zostanie wywołana
Modyfikatorparams może być używany z większą liczbą typów kolekcji, nie tylko z tablicami
Nowa składnia elementów rozszerzających (extension members), umożliwiająca definiowanie właściwości rozszerzających oraz statycznych rozszerzeń dla typów:
publicstaticclassRozszerzenia{// Rozszerzenie typu (statyczne)extension(string){publicstaticboolIsString(objecto)=>oisstring;}}
Słowo kluczowefield, umożliwiające dostęp do automatycznie generowanego pola zapasowego (backing field) wewnątrz właściwości (zamiast jego własnoręcznego tworzenia):
Prosty program napisany w języku C#. Po jego skompilowaniu i uruchomieniu wyświetlony zostanie napis"Podaj swoje imię: ". Po pobraniu imienia od użytkownika, zostanie ono wyświetlone w następnej linii.
usingSystem;publicclassPrzykladowaKlasa{publicstaticvoidMain(){Console.WriteLine("Podaj swoje imię:");stringimie=Console.ReadLine();Console.WriteLine($"Twoje imię to: {imie}");Console.WriteLine("Wciśnij dowolny klawisz by zakończyć program.");Console.ReadKey();}}
Inny program symulujący uniwersalną kostkę do gry, można w nim zobaczyć kilka podstawowych instrukcji języka C# oraz wykorzystanie funkcji instrukcji najwyższego poziomu.
intkostka;Randomliczba=new();stringinput=string.Empty;Console.Clear();while(true){Console.Write("Iluścienną kostką chcesz grać? ");try{kostka=int.Parse(Console.ReadLine());}catch{Console.WriteLine("Podano nieprawidłowe dane!");kostka=0;}if(kostka<4){Console.WriteLine("Kostka ma minimum 4 ściany.");}elsebreak;}Console.Clear();while(!input.Equals("q")){Console.WriteLine($"Wylosowana liczba to: {liczba.Next(kostka) + 1}\tAby zakończyć wciśnij Q + Enter");input=Console.ReadLine();}
Przykładowy program który działa jak stoper i aktualizuje się co sekundę:
usingSystem;usingSystem.Threading;classStopwatch{staticvoidMain(){intseconds=0;while(true){Console.Clear();// Wyczyść konsolę, aby zaktualizować czas na tym samym miejscuConsole.WriteLine("Czas: {0} sekund",seconds);Thread.Sleep(1000);// Poczekaj 1 sekundęseconds++;// Zwiększ licznik sekund o 1}}}