Konwencje nazewnictwa

Kompilator przyjmie każdą poprawną technicznie nazwę — nawet x1, dane2 i zmienna_final_OK. Ale kod czyta się dużo częściej, niż się go pisze. Ta lekcja pokazuje, jak nazywać rzeczy w C#, żeby po tygodniu nadal było wiadomo, o co chodzi.

C# PascalCase camelCase 35 min
CEL LEKCJI

Czego się dziś nauczysz

  • Odróżnisz zapis PascalCase od camelCase
  • Wskażesz, którym stylem zapisuje się zmienną, metodę, klasę i stałą
  • Poprawisz nazwy w cudzym kodzie zgodnie z konwencją C#
  • Ocenisz, czy nazwa opisuje zawartość, czy tylko zajmuje miejsce
  • Zastosujesz regułę zapisu skrótów i akronimów
TEORIA

Po co komu konwencje

Konwencje to nie kaprys. To umowa, dzięki której z samego wyglądu nazwy odczytasz, czym ona jest — jeszcze zanim sprawdzisz, gdzie została zadeklarowana.

jedna linia, trzy informacje
uczen.ZapiszDoPliku(nazwaPliku);
//  │        │            │
//  │        │            └── mała litera na początku → zmienna lokalna albo parametr
//  │        └── wielka litera + nawiasy → metoda, czyli coś, co się wykonuje
//  └── mała litera na początku → zmienna przechowująca obiekt

Nikt ci tego nie powiedział — po prostu tak wygląda kod w C#. Ta sama linia napisana bez konwencji (Uczen.zapiszdopliku(NazwaPliku)) niesie tę samą treść, ale trzeba się nad nią zatrzymać.

Konwencje są różne w różnych językach

W C# metody pisze się od wielkiej litery: WriteLine(). W Javie i JavaScripcie — od małej: writeLine(). W Pythonie zupełnie inaczej: write_line(). Żadna nie jest lepsza — po prostu każda społeczność umówiła się inaczej.

Zasada jest jedna: piszesz w C#, stosujesz konwencje C#. Kod pisany po javowemu od razu rzuca się w oczy jako obcy.

TEORIA

Dwa style zapisu

W C# używa się właściwie tylko dwóch sposobów sklejania wyrazów w nazwę. W obu nie ma spacji ani podkreśleń — granicę słów wyznacza wielka litera.

PascalCase

Każde słowo od wielkiej litery, łącznie z pierwszym.

ObliczSume
KontoBankowe
LiczbaUczniow

camelCase

Pierwsze słowo małą literą, każde kolejne od wielkiej.

obliczSume
kontoBankowe
liczbaUczniow

Skąd te nazwy

camelCase — od garbów wielbłąda: wielkie litery wystają ponad linię tekstu jak garby. PascalCase — od języka Pascal, w którym tak zapisywano nazwy.

Spotkasz jeszcze trzeci zapis: _camelCase, czyli camelCase z podkreśleniem na początku. W C# stosuje się go do prywatnych pól klasy — wrócimy do tego w bloku o programowaniu obiektowym.

TABELA DO ZAPAMIĘTANIA

Co zapisujemy którym stylem

ElementStylPrzykład
Zmienna lokalnacamelCaseint liczbaUczniow = 24;
Parametr metodycamelCasevoid Wypisz(string trescKomunikatu)
MetodaPascalCasevoid ObliczSrednia()
KlasaPascalCaseclass KontoBankowe
WłaściwośćPascalCasepublic string Imie { get; set; }
StałaPascalCaseconst double StawkaVat = 0.23;
Typ wyliczeniowyPascalCaseenum StatusZamowienia
Przestrzeń nazwPascalCasenamespace SzkolaApp.Dane
InterfejsI + PascalCaseinterface IPojazd
Prywatne pole klasy_camelCaseprivate int _licznik;

Jedna reguła zamiast dziesięciu wierszy tabeli

Wszystko, co widać z zewnątrz — od wielkiej litery. Wszystko, co jest schowane w środku — od małej.

Klasy, metody, właściwości i stałe są publiczną wizytówką twojego kodu, więc PascalCase. Zmienne lokalne i parametry żyją tylko w środku metody, więc camelCase. To pokrywa niemal wszystkie przypadki.

Stałe pisane WIELKIMI LITERAMI to nie jest styl C#

Zapis const int MAX_UCZNIOW = 30; pochodzi z języka C i z Javy. Spotkasz go w starszym kodzie C# i sam kompilator go przyjmie, ale oficjalne wytyczne Microsoftu mówią inaczej: stałe zapisujemy jak zwykłe składowe publiczne, czyli MaxUczniow.

Sprawdź to sam: w bibliotece .NET jest int.MaxValue i Math.PI, a nie INT_MAX_VALUE.

TEORIA

Co robi nazwę dobrą

Styl zapisu to dopiero połowa sprawy. Druga połowa — czy nazwa w ogóle coś mówi.

1. Nazwa ma opisywać zawartość

Program.cs
// ✗ Nic nie mówią
int d = 30;
string s = "Kowalski";
double x = 4.35;

// ✓ Wiadomo, o co chodzi
int dniDoWyplaty = 30;
string nazwiskoUcznia = "Kowalski";
double sredniaOcen = 4.35;

Wyjątek: krótkie nazwy w małym zasięgu

Litery i, j, k jako liczniki pętli są w porządku — to wieloletnia konwencja i każdy je rozumie. Podobnie x i y dla współrzędnych.

Zasada: im dłużej zmienna żyje, tym dłuższa powinna być jej nazwa. Zmienna używana w trzech linijkach może nazywać się i. Zmienna używana w całej metodzie już nie.

2. Nazwa metody zaczyna się od czasownika

Metoda coś robi, więc jej nazwa powinna to mówić.

✗ Słabo✓ Lepiej
Suma()ObliczSume() — wiadomo, że coś się wydarzy
Plik()ZapiszDoPliku()
Dane()PobierzDane() albo WczytajDane()

Metody zwracające prawdę lub fałsz nazywa się tak, żeby czytały się jak pytanie: CzyPelnoletni(), CzyPlikIstnieje(), MaUprawnienia().

3. Nazwy logiczne piszemy twierdząco

Program.cs
// ✗ Podwójne zaprzeczenie — trzeba się zastanowić
bool czyNieAktywny = false;
if (!czyNieAktywny) { /* czyli... aktywny? */ }

// ✓ Czyta się wprost
bool czyAktywny = true;
if (czyAktywny) { /* jasne */ }

4. Unikaj skrótów, których nie zna cały świat

✗ Zagadka✓ Zrozumiałe
usr, cnt, flg, tmp2uzytkownik, licznik, flaga, wartoscTymczasowa
id, url, min, max — te skróty zna każdy, można ich używać

5. Bez polskich znaków w nazwach

C# je dopuszcza, ale w praktyce się ich nie używa — psują się przy przenoszeniu kodu między systemami i utrudniają wyszukiwanie. Piszemy sredniaOcen, nie średniaOcen; liczbaUczniow, nie liczbaUczniów.

Polskie znaki zostają w tekstach dla użytkownika i w komentarzach — tam są jak najbardziej na miejscu:

Program.cs
// Obliczamy średnią ważoną — ocena z egzaminu liczy się podwójnie
double sredniaWazona = (ocenaZajec + 2 * ocenaEgzaminu) / 3.0;
Console.WriteLine($"Twoja średnia ważona to {sredniaWazona:F2}");
TEORIA

Skróty i akronimy — jedna prosta reguła

Co zrobić z nazwą zawierającą skrót w rodzaju XML, HTTP czy ID? Microsoft ma na to konkretną regułę, zależną od długości skrótu.

Długość skrótuZapisPrzykłady
2 literyobie wielkie IOException, DBConnection, UIElement
3 litery i więcejjak zwykłe słowo XmlReader, HttpClient, HtmlParser, JsonSerializer

To najczęściej mylona reguła w całym nazewnictwie C#

Intuicja podpowiada XMLReader i HTTPClient — bo przecież to skrótowce. A jednak poprawnie jest XmlReader i HttpClient.

Sprawdź w samej bibliotece .NET: znajdziesz tam HttpClient, XmlDocument, JsonSerializer — i obok IOException oraz DBNull. Dwuliterowe wielkimi, dłuższe jak słowo. Bez wyjątków.

W zapisie camelCase, czyli w zmiennych i parametrach, skrót na początku nazwy pisze się w całości małymi literami:

Program.cs
string xmlZawartosc;      // ✓   nie: xMLZawartosc
string htmlSzablon;       // ✓   nie: hTMLSzablon
string idUzytkownika;     // ✓   nie: iDUzytkownika
int ioBlad;               // ✓   nawet dwuliterowy, bo jest na początku
PRZYKŁAD Z OMÓWIENIEM

Ten sam program przed i po

Poniższy kod działa poprawnie. Problem w tym, że nikt go nie zrozumie — łącznie z autorem za miesiąc.

przed
const double VAT_STAWKA = 0.23;

double C = 1200.0;
int IL = 3;
double W = C * IL;
double V = W * VAT_STAWKA;
double B = W + V;
bool nie_ma_rabatu = B < 500;

Console.WriteLine(B);

A teraz to samo z nazwami zgodnymi z konwencją:

po
const double StawkaVat = 0.23;
const double ProgRabatu = 500.0;

double cenaJednostkowa = 1200.0;
int liczbaSztuk = 3;

double wartoscNetto = cenaJednostkowa * liczbaSztuk;
double kwotaVat = wartoscNetto * StawkaVat;
double wartoscBrutto = wartoscNetto + kwotaVat;

bool czyPrzysluguRabat = wartoscBrutto >= ProgRabatu;

Console.WriteLine($"Do zaplaty: {wartoscBrutto:F2} zl");

Co dokładnie się zmieniło

ByłoJestDlaczego
VAT_STAWKAStawkaVat Stałe w C# zapisujemy PascalCase, nie wielkimi literami z podkreśleniami. Przy okazji naturalna kolejność słów po polsku.
C, IL, W, V, Bpełne nazwy Pojedyncze litery nie mówią nic. IL było szczególnie mylące — tak nazywa się kod pośredni .NET z lekcji 02.
nie_ma_rabatuczyPrzysluguRabat Trzy poprawki naraz: podkreślenia zamienione na camelCase, zaprzeczenie na formę twierdzącą, a warunek na sensowny — poprzedni sprawdzał, czy kwota jest mniejsza niż próg.
Console.WriteLine(B);opisany komunikat Sama liczba na ekranie nic nie znaczy. Format F2 zaokrągla do groszy.

Visual Studio zmieni nazwę za ciebie

Nie poprawiaj nazw ręcznie w każdym miejscu. Ustaw kursor na nazwie i naciśnij Ctrl + R, Ctrl + R — zmiana obejmie wszystkie wystąpienia w projekcie. To bezpieczniejsze niż zamiana tekstu, bo edytor rozumie kod i nie ruszy przypadkowo podobnego słowa w komentarzu czy w innym zasięgu.

CZĘSTE BŁĘDY

Na co uważać

ZapisCo jest nie tak
class uczenKlasa od małej litery. Powinno być Uczen.
void obliczSume()Metoda od małej litery — to zapis z Javy. W C#: ObliczSume().
int Wiek = 17; (lokalna)Zmienna lokalna od wielkiej litery. Powinno być wiek.
int liczba_uczniow;Podkreślenia rozdzielające słowa to styl Pythona i C. W C#: liczbaUczniow.
class PojazdInterfaceInterfejs oznaczamy przedrostkiem, nie przyrostkiem: IPojazd.
const int MAX = 100;Wielkie litery to konwencja z innych języków. W C#: Max albo lepiej MaksymalnaLiczba.
class XMLParserAkronim trzyliterowy zapisujemy jak słowo: XmlParser.
double średnia;Technicznie poprawne, ale polskich znaków w nazwach się nie używa: srednia.
bool flaga;„Flaga” czego? Nazwa nie mówi, co oznacza wartość prawda: czyZapisano.

Konwencje to nie błędy kompilacji

Żaden z powyższych zapisów nie zatrzyma budowania programu — kod zadziała. Dlatego łatwo je zaniedbać. Warto jednak wyrobić sobie nawyk od początku: na egzaminie zawodowym czytelność kodu podlega ocenie, a w pracy zespołowej niespójne nazewnictwo to realne utrudnienie.

ZADANIA

Zadania

ZAD 1Który styl?★☆☆

Dla każdego elementu zapisz, jakim stylem powinien być nazwany, i podaj przykład: zmienna lokalna przechowująca liczbę stron, metoda drukująca raport, klasa opisująca fakturę, stała z maksymalną liczbą prób, interfejs dla czegoś, co da się zapisać.

pokaż rozwiązanie
ElementStylPrzykład
zmienna lokalnacamelCaseint liczbaStron
metodaPascalCasevoid DrukujRaport()
klasaPascalCaseclass Faktura
stałaPascalCaseconst int MaksymalnaLiczbaProb = 3;
interfejsI + PascalCaseinterface IZapisywalny

Zwróć uwagę na nazwę metody — zaczyna się od czasownika, bo metoda coś robi. Raport() byłoby gorsze, bo brzmi jak rzecz, a nie jak czynność.

ZAD 2Popraw nazwy★★☆

Przepisz poniższy kod, poprawiając wszystkie nazwy zgodnie z konwencjami C#. Nie zmieniaj działania programu.

do poprawienia
const int MAX_OCEN = 5;

class uczen_szkoly
{
    public string IMIE;
    private int wiek_ucznia;

    public void oblicz_srednia() { }

    public bool nie_zdal() { return false; }
}

class HTMLGenerator { }
pokaż rozwiązanie
const int MaksymalnaLiczbaOcen = 5;

class UczenSzkoly
{
    public string Imie;
    private int _wiekUcznia;

    public void ObliczSrednia() { }

    public bool CzyZdal() { return true; }
}

class HtmlGenerator { }

StałaMAX_OCEN to zapis z C i Javy. W C# PascalCase, a przy okazji pełne słowo zamiast skrótu.

Klasauczen_szkoly ma dwa problemy naraz: małą literę i podkreślenie. Poprawnie UczenSzkoly.

Pole publiczneIMIE wielkimi literami to znów styl z innego języka. Publiczne składowe zapisujemy PascalCase: Imie.

Pole prywatnewiek_ucznia zamieniamy na _wiekUcznia: podkreślenie na początku, dalej camelCase.

Metody — obie od wielkiej litery, bez podkreśleń. nie_zdal dodatkowo poprawiamy na formę twierdzącą CzyZdal; zauważ, że wtedy trzeba też odwrócić zwracaną wartość, żeby program działał tak samo.

Klasa z akronimem — HTML ma cztery litery, więc zapisujemy go jak zwykłe słowo: HtmlGenerator.

ZAD 3Akronimy★★☆

Zapisz poprawnie nazwy klas zawierających skróty: czytnik plików XML, klient usługi HTTP, wyjątek operacji wejścia-wyjścia (IO), konwerter formatu JSON, element interfejsu użytkownika (UI). Uzasadnij każdą decyzję.

pokaż rozwiązanie
SkrótDługośćNazwaReguła
XML3 literyXmlReader3+ → jak zwykłe słowo
HTTP4 literyHttpClient3+ → jak zwykłe słowo
IO2 literyIOException2 → obie wielkie
JSON4 literyJsonConverter3+ → jak zwykłe słowo
UI2 literyUIElement2 → obie wielkie

Wszystkie pięć nazw istnieje naprawdę w bibliotece .NET — możesz je wpisać w Visual Studio i sprawdzić, że edytor je podpowie. To najlepszy sposób weryfikacji konwencji: zobacz, jak nazwał to Microsoft.

ZAD 4Nazwij to lepiej★★☆

Poniższe nazwy są zapisane poprawnym stylem, ale i tak są złe. Wymyśl lepsze i napisz jednym zdaniem, dlaczego twoja wersja jest lepsza.

do poprawienia
bool flaga;
int licznik2;
string dane;
void Zrob();
double wartosc;
przykładowe rozwiązanie
bool czyPlikZapisany;        // wiadomo, co znaczy „prawda"
int liczbaBlednychProb;      // cyfra na końcu nazwy niczego nie tłumaczy
string trescWiadomosci;      // „dane" to każdy string na świecie
void WyslijWiadomosc();      // czasownik mówi, co metoda robi
double cenaBrutto;           // „wartość" nie mówi, czego

To zadanie nie ma jednej poprawnej odpowiedzi — wszystko zależy od tego, co program naprawdę robi. Chodzi o wyrobienie odruchu: zanim wpiszesz nazwę, zadaj sobie pytanie „czy ktoś obcy zgadnie, co tu jest?”.

Szczególnie zwróć uwagę na licznik2. Cyfra na końcu nazwy prawie zawsze znaczy, że autorowi skończyły się pomysły — i że istnieje gdzieś licznik1, którego nikt już nie odróżni od tego drugiego.

ZAD 5Ćwiczenie na własnym kodzie★★☆

Wróć do programów napisanych w lekcjach 1–4. Przejrzyj wszystkie nazwy zmiennych i popraw te, które nie spełniają dzisiejszych zasad. Użyj skrótu do zmiany nazwy zamiast poprawiania ręcznego.

na co zwrócić uwagę

Typowe rzeczy, które znajdziesz we własnym kodzie sprzed dzisiejszej lekcji:

  • zmienne o nazwach a, b, x poza pętlami
  • polskie znaki, które wpisały się same przy pisaniu po polsku
  • liczby wpisane wprost zamiast nazwanych stałych
  • zmienne logiczne bez przedrostka czy

Po poprawkach uruchom program i sprawdź, czy nadal działa tak samo. Zmiana nazwy nigdy nie powinna zmienić działania — jeśli zmieniła, coś poszło nie tak przy zamianie.

PODSUMOWANIE

Co trzeba zapamiętać

  • PascalCase — każde słowo od wielkiej litery. camelCase — pierwsze od małej, kolejne od wielkiej.
  • Reguła w jednym zdaniu: widoczne z zewnątrz od wielkiej litery, schowane w środku od małej.
  • Klasy, metody, właściwości, stałe i przestrzenie nazw — PascalCase.
  • Zmienne lokalne i parametry — camelCase. Prywatne pola klasy — _camelCase.
  • Interfejsy zaczynają się od I: IPojazd, IZapisywalny.
  • Stałych nie zapisujemy WIELKIMI_LITERAMI — to konwencja z innych języków.
  • Skróty dwuliterowe wielkimi (IOException), trzyliterowe i dłuższe jak zwykłe słowo (XmlReader, HttpClient).
  • Nazwa metody zaczyna się od czasownika, nazwa logiczna jest twierdząca.
  • Bez polskich znaków w nazwach. W komunikatach i komentarzach — jak najbardziej.
  • Zmiana nazwy w całym projekcie: Ctrl + R, Ctrl + R.