1. Jak poprawnie stworzyć obiekt
Operator new w C# — to taka magiczna przycisk, który zamienia schematyczny "rysunek techniczny" (naszą klasę) w prawdziwą instancję (obiekt), z którym można już coś zrobić. Mówiąc prościej: klasa określa co obiekt potrafi i jakie ma właściwości, a new — tworzy ten obiekt w pamięci komputera.
Bez operatora new nasze klasy byłyby jak projekty bez budynków: można podziwiać, dyskutować, ale ani poskakać, ani rozlać herbaty na fotel z alkantary się nie da.
Jeśli klasa to przepis na pizzę, to operator new to kucharz, który według tego przepisu robi prawdziwą, pyszną pizzę. Obiekt to efekt jego pracy: pizza w pudełku, którą można już zjeść.
Składnia
Zobaczmy, jak użyć tego wszechmocnego new. Oto podstawowa składnia, jeśli mamy klasę Contact:
Contact cont = new Contact();
- Contact po lewej — to typ zmiennej, którą tworzymy.
- cont — nazwa zmiennej (wybieraj sensowne, jeśli nie chcesz cierpieć podczas debugowania w przyszłości).
- new Contact() — wywołanie operatora new, który tworzy obiekt typu Contact.
W pamięci
Gdy ten kod się wykona, system operacyjny rezerwuje kawałek pamięci dla nowego obiektu i zwraca referencję (adres), pod którym ten obiekt "żyje". Ta referencja jest przechowywana w zmiennej cont.
Schemat
+------------------+ +--------------------+
| zmienna cont | ---------> | Obiekt Contact |
+------------------+ +--------------------+
|
| (zawiera imię, telefon, email, ...)
|
adres
2. Tworzymy obiekty kontaktów
W poprzednich przykładach wymyśliliśmy taką klasę:
public class Contact
{
public string Name;
public string Phone;
public string Email;
}
Teraz stworzymy nowy obiekt typu Contact:
Contact friend = new Contact();
friend.Name = "Ivan Ivanov";
friend.Phone = "+1-999-123-45-67";
friend.Email = "ivan@example.com";
Console.WriteLine($"Imię: {friend.Name}, Telefon: {friend.Phone}, Email: {friend.Email}");
Co tu się dzieje:
- Tworzymy obiekt za pomocą new Contact().
- Przypisujemy wartości do jego pól.
- Wyświetlamy dane na ekranie.
Przykład 2:
Dodajmy pracę z kilkoma kontaktami — stworzymy jeszcze jeden obiekt:
Contact boss = new Contact();
boss.Name = "Anastazja Siergiejewna";
boss.Phone = "+1-888-765-43-21";
boss.Email = "nastya@company.com";
Console.WriteLine($"Szef: {boss.Name}, Telefon: {boss.Phone}");
Czy to nie przypomina wypełniania ankiety dla każdego znajomego? Właśnie tak działają obiekty: każda stworzona instancja dostaje swoje unikalne wartości i przechowuje je osobno od innych!
3. Użycie tablicy obiektów
Jeśli musimy przechowywać nie jeden czy dwa, ale powiedzmy dziesięć kontaktów, logiczne jest trzymać je w tablicy:
Contact[] contacts = new Contact[3]; // tablica na 3 obiekty
contacts[0] = new Contact();
contacts[0].Name = "Denis";
contacts[0].Phone = "+7-911-111-22-33";
contacts[1] = new Contact();
contacts[1].Name = "Maria";
contacts[1].Phone = "+7-915-123-45-67";
contacts[2] = new Contact();
contacts[2].Name = "Piotr";
contacts[2].Phone = "+7-921-543-21-00";
// Wyświetlimy wszystkich na ekranie
for (int i = 0; i < contacts.Length; i++)
{
Console.WriteLine($"Kontakt {i+1}: {contacts[i].Name}, {contacts[i].Phone}");
}
Ważne: używamy new dla każdego elementu tablicy! Samo stworzenie tablicy nie tworzy obiektów, a tylko przygotowuje miejsce na referencje do nich.
4. Operator new i wartość domyślna
Czasem pojawia się pytanie — a jeśli po prostu zadeklaruję zmienną typu Contact, ale nie przypiszę jej obiektu przez new, co się stanie?
Contact someContact;
someContact.Name = "Błąd"; // Błąd kompilacji!
Jeśli napiszesz:
Contact someContact = null;
to przy próbie dostępu do someContact.Name twój program "wywali się" z dobrze znanym wyjątkiem:
System.NullReferenceException: Referencja do obiektu nie wskazuje na instancję obiektu.
Żeby tego uniknąć, zawsze inicjalizuj obiekty za pomocą new przed użyciem.
5. Wywołanie konstruktora
Gdy piszesz new Contact(), w tym momencie wywoływana jest specjalna metoda — konstruktor. Na razie nasza klasa nie ma jawnych konstruktorów, więc wywoływany jest domyślny konstruktor, który tworzy obiekt, a wszystkie pola wypełnia wartościami domyślnymi (null dla typów referencyjnych i zerem dla liczbowych).
W następnym wykładzie dowiesz się, jak tworzyć własne konstruktory — na przykład od razu przekazywać imię i telefon. Na razie działa tylko konstruktor bez parametrów.
Przykłady z życia codziennego
Praca z obiektami przez operator new — to codzienność każdego C#-developera. Wyobraź sobie, że:
- Tworzysz użytkownika na stronie — w kodzie pojawia się nowy obiekt User.
- Otwierasz zamówienie w sklepie internetowym — pojawia się nowy Order.
- Wprowadzasz dane o książce — nowy obiekt Book.
W każdej nowoczesnej aplikacji w C# zobaczysz tysiące linii z operatorem new.
Pamięć przed stworzeniem obiektu
Contact firstContact; // Zmienna, ale na nic nie wskazuje
+--------------------------+
| firstContact |----> null (nic!)
+--------------------------+
Po stworzeniu obiektu
Contact firstContact = new Contact();
+--------------------------+ +----------------------+
| firstContact |---------------->| Obiekt Contact |
+--------------------------+ +----------------------+
6. Praktyczny przykład
Załóżmy, że chcemy pozwolić użytkownikowi tworzyć nowe kontakty przez wpisywanie z klawiatury:
Console.WriteLine("Wpisz imię:");
string name = Console.ReadLine();
Console.WriteLine("Wpisz telefon:");
string phone = Console.ReadLine();
Contact newContact = new Contact();
newContact.Name = name;
newContact.Phone = phone;
Console.WriteLine($"Zapisano kontakt: {newContact.Name}, {newContact.Phone}");
Teraz każdy wpis użytkownika stworzy swój unikalny obiekt w pamięci, który można przechowywać, zmieniać, wyświetlać — robić z nim co tylko chcesz!
7. Typowe błędy i zabawne pułapki
Błąd nr 1: zapomniałeś wywołać new przed pracą z obiektem.
Jeśli zadeklarujesz zmienną, ale jej nie zainicjalizujesz, ryzykujesz błąd kompilacji albo NullReferenceException w trakcie działania programu. To klasyka: zadeklarowałeś obiekt — od razu go twórz przez new, jeśli naprawdę go potrzebujesz.
Błąd nr 2: stworzyłeś tablicę obiektów, ale nie stworzyłeś samych obiektów.
Oto częsta pułapka: tworzysz tablicę typu Contact[], ale zapominasz, że w środku są tylko null. Próba dostępu do contacts[0].Name wywoła crash. Najpierw musisz zainicjalizować każdy element tablicy osobno: contacts[i] = new Contact();.
Błąd nr 3: pomyliłeś metodę z właściwością.
Czasem początkujący myślą, że metodę można użyć jak pole: piszą student.GetName zamiast student.GetName(). To zadziała, jeśli nie próbujesz od razu użyć wyniku — ale kompilator zacznie się burzyć, jeśli spróbujesz wstawić "metodę" tam, gdzie oczekuje wartości. Zawsze sprawdzaj: metoda musi być wywołana z nawiasami, nawet jeśli nie przyjmuje parametrów.
GO TO FULL VERSION