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 29
W 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