NullReferenceException w C#

NullReferenceException w C# – skąd się bierze i jak go naprawić?

NullReferenceException w C# – skąd się bierze i jak go naprawić?

NullReferenceException to jeden z najczęstszych błędów, z jakimi spotykają się osoby uczące się C#. Komunikat “Object reference not set to an instance of an object” wygląda groźnie, ale zwykle oznacza prostą rzecz: próbujesz użyć obiektu, który ma wartość null.

W tym poradniku pokażę Ci, czym jest null w C#, dlaczego pojawia się NullReferenceException i jak naprawić ten błąd krok po kroku. Zobaczysz proste przykłady z obiektem, listą, metodą zwracającą null oraz operatorami ?. i ??.


Co oznacza null w C#?

W C# null oznacza brak obiektu.

Zmienna istnieje, ale nie wskazuje na żaden konkretny obiekt w pamięci. To trochę tak, jakbyś miał/a etykietę na pudełko, ale samego pudełka jeszcze nie było.

Zobacz prosty przykład:

string? name = null;

Console.WriteLine(name.Length);

Ten kod spowoduje błąd, ponieważ próbujemy odczytać długość tekstu, którego nie ma. Zmienna name nie zawiera napisu. Zawiera null.

Efekt:

System.NullReferenceException:
Object reference not set to an instance of an object.

Najważniejsze: problem nie polega na tym, że właściwość Length jest zła. Problem polega na tym, że name jest nullem.


Czym jest NullReferenceException?

NullReferenceException pojawia się wtedy, gdy próbujesz użyć obiektu, który nie istnieje.

Najczęstszy schemat wygląda tak:

public class User
{
    public string Name { get; set; }
}

User user = null;

Console.WriteLine(user.Name);

W tym przykładzie mamy klasę User, ale zmienna user nie zawiera żadnego użytkownika. Jest nullem.

Dlatego linia:

Console.WriteLine(user.Name);

spowoduje wyjątek.

Program próbuje wejść do właściwości Name, ale nie ma obiektu user, z którego mógłby tę właściwość odczytać.


Dlaczego pojawia się komunikat „Object reference not set…”?

Pełny komunikat błędu brzmi często:

Object reference not set to an instance of an object.

Po ludzku oznacza to:

Próbujesz użyć referencji do obiektu, ale ta referencja nie wskazuje na żaden utworzony obiekt.

Inaczej mówiąc:

  • zmienna została zadeklarowana,
  • ale nie przypisano do niej obiektu,
  • albo metoda zwróciła null,
  • a kod mimo tego próbuje użyć właściwości lub metody tego obiektu.

Najczęstsze przyczyny NullReferenceException w C

NullReferenceException może pojawić się w wielu miejscach. Najczęściej przyczyną jest jedna z poniższych sytuacji.

Obiekt nie został utworzony przez new

Błędny kod:

User user = null;

user.Name = "Anna";

Poprawny kod:

User user = new User();

user.Name = "Anna";

Console.WriteLine(user.Name);

Samo zadeklarowanie zmiennej nie zawsze tworzy obiekt. Przy typach referencyjnych często trzeba użyć new.


Metoda zwraca null

Błąd może pojawić się także wtedy, gdy metoda nie znalazła danych i zwróciła null.

User user = GetUser();

Console.WriteLine(user.Name);

static User GetUser()
{
    return null;
}

W tym przykładzie problem nie jest w Console.WriteLine. Problem pojawia się wcześniej, bo metoda GetUser() zwraca null.

To bardzo częsta sytuacja w realnych aplikacjach, np. przy szukaniu użytkownika w bazie danych.


Lista nie została zainicjalizowana

Ten błąd często dotyczy też list.

Błędny kod:

List<string> names = null;

names.Add("Anna");

Poprawny kod:

List<string> names = new();

names.Add("Anna");

Lista też jest obiektem. Jeśli nie zostanie utworzona, nie można dodać do niej elementów.


Właściwość wewnątrz obiektu jest nullem

Czasem sam obiekt istnieje, ale jego właściwość jest nullem.

Przykład:

User user = new User();

Console.WriteLine(user.Name.Length);

Jeżeli Name nie ma wartości, program może wysypać się na user.Name.Length.

Bezpieczniejsza wersja:

User user = new User();

Console.WriteLine(user.Name?.Length ?? 0);

Tutaj program sprawdza, czy Name nie jest nullem. Jeśli jest, zwraca 0.


Jak znaleźć miejsce błędu w Visual Studio?

Najprostsza metoda to debugowanie.

Załóżmy, że masz taki kod:

User user = GetUser();

Console.WriteLine(user.Name);

static User GetUser()
{
    return null;
}

Co zrobić krok po kroku?

  1. Ustaw breakpoint na linii:
User user = GetUser();
  1. Uruchom program w trybie debugowania.
  2. Sprawdź wartość zmiennej user.
  3. Jeśli user == null, cofnij się do metody, która tę wartość zwróciła.
  4. Sprawdź, dlaczego metoda zwróciła null.

Najważniejsze pytanie przy tym błędzie brzmi:

Która zmienna jest nullem?

Nie zgaduj. Sprawdź to w debuggerze.


Jak naprawić NullReferenceException?

Nie ma jednej uniwersalnej naprawy. Wszystko zależy od tego, czy null jest poprawną sytuacją, czy błędem w logice programu.

Poniżej znajdziesz najczęstsze sposoby.


Naprawa 1: sprawdzenie if

Najprostsze rozwiązanie to zwykłe sprawdzenie, czy obiekt nie jest nullem.

User user = GetUser();

if (user != null)
{
    Console.WriteLine(user.Name);
}
else
{
    Console.WriteLine("Nie znaleziono użytkownika.");
}

To dobre rozwiązanie, gdy brak danych jest normalnym scenariuszem.

Przykład: użytkownik o danym adresie e-mail nie istnieje w bazie. Wtedy null może być poprawną odpowiedzią.


Naprawa 2: operator ?.

Operator ?. pozwala bezpiecznie odwołać się do właściwości lub metody tylko wtedy, gdy obiekt nie jest nullem.

User user = GetUser();

Console.WriteLine(user?.Name);

Ten zapis oznacza:

Wejdź do Name tylko wtedy, gdy user nie jest nullem.

Jeśli user jest nullem, program się nie wysypie. Wynikiem będzie null.


Naprawa 3: operator ??

Operator ?? pozwala ustawić wartość domyślną, gdy po lewej stronie pojawi się null.

User user = GetUser();

Console.WriteLine(user?.Name ?? "Brak użytkownika");

Ten kod oznacza:

  • jeśli user istnieje i ma Name, wypisz Name,
  • jeśli wynik jest nullem, wypisz "Brak użytkownika".

To bardzo wygodne rozwiązanie w prostych przypadkach.


Naprawa 4: poprawne utworzenie obiektu

Jeśli obiekt powinien istnieć, trzeba go utworzyć.

Błędny kod:

User user = null;

user.Name = "Anna";

Poprawny kod:

User user = new User();

user.Name = "Anna";

Console.WriteLine(user.Name);

Dopiero new User() tworzy obiekt, na którym można pracować.


Naprawa 5: oznacz typ jako nullable

W nowszych wersjach C# możesz jawnie oznaczyć, że dana zmienna może mieć wartość null.

static User? FindUserByEmail(string email)
{
    if (email == "anna@example.com")
    {
        return new User { Name = "Anna" };
    }

    return null;
}

Znak ? przy typie User? informuje, że metoda może zwrócić użytkownika albo null.

Potem trzeba to obsłużyć:

User? user = FindUserByEmail("test@example.com");

if (user == null)
{
    Console.WriteLine("Nie znaleziono użytkownika.");
    return;
}

Console.WriteLine(user.Name);

To czytelny i bezpieczny styl pisania kodu.


string czy string? – jaka jest różnica?

W nowoczesnym C# możesz spotkać dwa zapisy:

string name = "Anna";

oraz:

string? name = null;

Różnica jest ważna:

  • string oznacza, że zmienna nie powinna być nullem,
  • string? oznacza, że zmienna może być nullem.

Przykład bezpiecznego użycia:

string? name = null;

Console.WriteLine(name?.Length ?? 0);

Dzięki nullable reference types kompilator może ostrzegać Cię przed błędami wcześniej, zanim program wysypie się podczas działania.


Czy NullReferenceException należy łapać przez try-catch?

W większości przypadków nie.

NullReferenceException zwykle oznacza, że program próbował użyć czegoś, czego nie przygotował. Lepiej znaleźć przyczynę i poprawić logikę, niż tylko ukryć błąd przez catch.

Nie najlepszy pomysł:

try
{
    Console.WriteLine(user.Name);
}
catch (NullReferenceException)
{
    Console.WriteLine("Coś było nullem.");
}

Lepsze podejście:

if (user == null)
{
    Console.WriteLine("Nie znaleziono użytkownika.");
    return;
}

Console.WriteLine(user.Name);

try-catch zostaw na sytuacje naprawdę wyjątkowe. Przy null zwykle lepiej sprawdzić dane wcześniej.


Kompletna przykładowa aplikacja

Poniżej znajdziesz prosty kod, który pokazuje kilka bezpiecznych sposobów pracy z null.

using System;
using System.Collections.Generic;

public class User
{
    public string Name { get; set; } = string.Empty;
}

public class Program
{
    public static void Main()
    {
        // Przykład 1: null na stringu
        string? name = null;

        Console.WriteLine(name?.Length ?? 0);

        // Przykład 2: metoda może zwrócić null
        User? user = GetUser();

        if (user != null)
        {
            Console.WriteLine(user.Name);
        }
        else
        {
            Console.WriteLine("Nie znaleziono użytkownika.");
        }

        // Przykład 3: poprawne utworzenie obiektu
        User newUser = new User();

        newUser.Name = "Anna";

        Console.WriteLine(newUser.Name);

        // Przykład 4: lista
        List<string> names = new();

        names.Add("Anna");
        names.Add("Marek");

        foreach (string item in names)
        {
            Console.WriteLine(item);
        }

        // Przykład 5: metoda szukająca użytkownika
        User? foundUser = FindUserByEmail("test@example.com");

        if (foundUser == null)
        {
            Console.WriteLine("Użytkownik nie istnieje.");
            return;
        }

        Console.WriteLine(foundUser.Name);
    }

    private static User? GetUser()
    {
        return null;
    }

    private static User? FindUserByEmail(string email)
    {
        if (email == "anna@example.com")
        {
            return new User { Name = "Anna" };
        }

        return null;
    }
}

Checklista: jak naprawić NullReferenceException?

Gdy zobaczysz NullReferenceException, przejdź przez tę checklistę:

  • Sprawdź linię, w której program się zatrzymał.
  • Ustal, która zmienna może być nullem.
  • Użyj debuggera w Visual Studio.
  • Sprawdź, skąd przyszła wartość null.
  • Jeśli brak danych jest normalny, dodaj if.
  • Jeśli chcesz bezpiecznie odczytać właściwość, użyj ?..
  • Jeśli potrzebujesz wartości domyślnej, użyj ??.
  • Jeśli obiekt powinien istnieć, utwórz go przez new.
  • Oznacz możliwe nulle jako User?, string? itd.
  • Nie ukrywaj problemu przez przypadkowy try-catch.

Najczęstsze błędy początkujących

Błąd 1: „Przecież zadeklarowałem zmienną”

Deklaracja zmiennej to nie zawsze utworzenie obiektu.

User user;

To jeszcze nie znaczy, że masz gotowego użytkownika.


Błąd 2: Nadużywanie ?.

Operator ?. jest wygodny, ale nie powinien ukrywać błędów logicznych.

Jeśli użytkownik zawsze powinien istnieć, a mimo to masz null, trzeba znaleźć przyczynę. Nie wystarczy wszędzie dopisać ?..


Błąd 3: Łapanie wszystkiego przez try-catch

try-catch nie powinien być sposobem na normalny przepływ programu. Jeśli możesz sprawdzić warunek wcześniej, zwykle warto to zrobić.


Zobacz także — powiązane artykuły

👉 MCP w .NET (C#) – jak zbudować serwer AI krok po kroku

👉 Tworzenie klas i obiektów w C# — kompletny przewodnik

👉 Pattern Matching w C# – switch expressions i type patterns


Podsumowanie

NullReferenceException w C# pojawia się wtedy, gdy próbujesz użyć obiektu, który ma wartość null.

Najważniejsze nie jest zapamiętanie jednego magicznego rozwiązania. Najważniejsze jest zrozumienie, skąd ten null się wziął.

W praktyce najczęściej pomogą Ci:

  • debugger,
  • sprawdzenie if,
  • operator ?.,
  • operator ??,
  • poprawne tworzenie obiektu przez new,
  • nullable reference types.

Pamiętaj: celem nie jest tylko „uciszenie błędu”. Celem jest świadoma decyzja, co aplikacja ma zrobić, gdy jakichś danych brakuje.


Call to Action

👉 Masz problem z NullReferenceException w swoim kodzie?
Zostaw komentarz pod wpisem i opisz, w której linii pojawia się błąd.

👉 A jeśli uczysz się C# i .NET od podstaw, sprawdź więcej materiałów na dev-hobby.pl i zobacz kolejne poradniki z serii dla początkujących programistów.

👉 subskrybuj nasz kanał na YT!

👉 udostępnij artykuł komuś, kto zaczyna z programowaniem

Dołącz do “Od Zera do .NET Developera”

Zacznij swoją przygodę z programowaniem w oparciu o sprawdzone praktyki rynkowe. Wybierz kompletną ścieżkę rozwoju i zbuduj solidne fundamenty.

Dołącz do ścieżki teraz →
Masz pytania? Napisz: mariuszjurczenko@dev-hobby.pl

Dodaj komentarz