W języku C# klasy tworzy się podobnie jak w Javie, choć są elementy bardziej przypominające C++. Należy do nich pojęcie struktury.
Tak jak w C++ i Javie „normalne” klasy definiuje się używając słowa kluczowego class.
Można jednak użyć również słowa struct. W Javie jest to niedopuszczalne, w C++ w zasadzie równoważne użyciu class. W C# natomiast obiekty struktur i klas są zupełnie innego typu obiektami. Obiekty klas powstają na stercie (w pamięci wolnej), a deklarowana nazwa (poprzedzająca słowo kluczowe new) jest nazwą nie obiektu, ale odniesienia do obiektu (tak jak w Javie). Natomiast obiekty struktur tworzone są na stosie, tak jak zwykłe lokalne zmienne typów wbudowanych i tak jak w C++ obiekty klas i struktur które tworzymy na stosie (a nie na stercie za pomocą new). W C# nawet jeśli użyjemy new obiekt struktury (ale nie klasy) tworzony jest na stosie. Obowiązuje dla takich obiektów „semantyka wartości”, co w szczególności oznacza, że nazwa może być traktowana jako nazwa obiektu, a nie odnośnika.
Ma to daleko idące konsekwencje. Rozpatrzmy przykład:
1. using System; 2. 3. class OSOBA { 4. public string nazwisko; 5. public int wiek; 6. public OSOBA(string n, int w) { 7. nazwisko = n; 8. wiek = w; 9. } 10. } 11. 12. struct Osoba { 13. public string nazwisko; 14. public int wiek; 15. public Osoba(string n, int w) { 16. nazwisko = n; 17. wiek = w; 18. } 19. } 20. 21. class StruClass { 22. public static void Main() { 23. OSOBA kJanek = new OSOBA("Janek",18); 24. OSOBA kPiotr = new OSOBA("Piotr",19); 25. 26. Console.WriteLine("Po utworzeniu obiektow " + 27. "klasy:\n" + 28. "Janek: " + kJanek.nazwisko + " " + 29. kJanek.wiek + " : " + "Piotr: " + 30. kPiotr.nazwisko + " " + kPiotr.wiek); 31. 32. kJanek = kPiotr; 33. kPiotr.wiek = 29; 34. 35. Console.WriteLine("Po przypisaniu i zmianie " + 36. "wieku Piotra:\n" + 37. "Janek: " + kJanek.nazwisko + " " + 38. kJanek.wiek + " : " + "Piotr: " + 39. kPiotr.nazwisko + " " + kPiotr.wiek + "\n"); 40. 41. Osoba sJanek = new Osoba("Janek",18); 42. Osoba sPiotr = new Osoba("Piotr",19); 43. 44. Console.WriteLine("Po utworzeniu obiektow " + 45. "struktury:\n" + 46. "Janek: " + sJanek.nazwisko + " " + 47. sJanek.wiek + " : " + "Piotr: " + 48. sPiotr.nazwisko + " " + sPiotr.wiek); 49. 50. sJanek = sPiotr; 51. sPiotr.wiek = 29; 52. 53. Console.WriteLine("Po przypisaniu i zmianie " + 54. "wieku Piotra:\n" + 55. "Janek: " + sJanek.nazwisko + " " + 56. sJanek.wiek + " : " + "Piotr: " + 57. sPiotr.nazwisko + " " + sPiotr.wiek + "\n"); 58. } 59. }
Po utworzeniu obiektow klasy: Janek: Janek 18 : Piotr: Piotr 19 Po przypisaniu i zmianie wieku Piotra: Janek: Piotr 29 : Piotr: Piotr 29 Po utworzeniu obiektow struktury: Janek: Janek 18 : Piotr: Piotr 19 Po przypisaniu i zmianie wieku Piotra: Janek: Piotr 19 : Piotr: Piotr 29W liniach 23-24 tworzymy dwa obiekty klasy: odnośniki do nich nazywają się kJanek i kPiotr. W linii 32 dokonujemy przypisania ' kJanek = kPiotr;' po czym zmieniamy wiek Piotra (linia 33). W liniach 35-39 drukujemy informacje o obu obiektach: widzimy, że są one identyczne. Zmieniliśmy wiek Piotra, ale wiek Janka też się przy tym zmienił! Takie zachowanie znamy z Javy. Przyczyną tego jest to, że przypisanie ' kJanek = kPiotr;' przepisało odniesienie do obiektu opisującego Piotra do odnośnika kJanek. Teraz wartością obu odnośników, kJanek i kPiotr, jest odniesienie do tego samego obiektu. Obiekt pierwotnie wskazywany przez odnośnik kJanek został „zgubiony” i może być usunięty przez odśmiecacz.
Linie 41-57 są powtórzeniem linii 23-39 z tą różnicą, że teraz tworzymy nie obiekty klasy, ale obiekty struktury. Jak widzimy, przypisanie ' sJanek = sPiotr;' spowodowało przepisanie informacji zawartej w obiekcie sPiotr do obiektu sJanek, ale nie utożsamiło tych dwóch obiektów. Zmiana wieku Piotra w linii 51 zmodyfikowała tylko obiekt sPiotr, ale nie sJanek, co widzimy z wydruku: obiekt sJanek zawiera informacje takie jakie zostały tam wpisane za pomocą przypisania ' sJanek = sPiotr;'. Wiek Piotra został potem zmieniony, ale nie miało to już wpływu na wiek zapisany w obiekcie kJanek. Tak więc w tym przypadku mamy cały czas do czynienia z dwoma obiektami, a nazwy sPiotr i sJanek są nazwami tych obiektów, a nie odnośników do nich.
Podsumowując
Oczywiście klasy, struktury, konstruktory, tworzenie obiektów itd. to tematy bardzo obszerne i każdy język obiektowy ma mnóstwo specyficznych cech. Ponieważ naszym właściwym celem jest poznanie języka C++, więc nie będziemy tu szerzej omawiać szczegółowo różnic pomiędzy C# a Javą i C++, poprzestając na zasygnalizowaniu tylko niektórych z nich.
T.R. Werner, 21 lutego 2016; 20:17