En el Mòdul 1 vas aprendre a declarar variables, a treballar amb arrays i a manipular cadenes de text, però tot el codi que vas escriure fins ara s'executava sempre de la mateixa manera, línia rere línia, sense marge per reaccionar a les dades. A la vida real, BiblioTechConsola necessita prendre decisions: es pot deixar aquest llibre? el soci ja té massa préstecs actius? l'ISBN introduït té un format vàlid? Aquesta lliçó presenta les sentències condicionals, el mecanisme amb què un programa en C# decideix quin camí seguir segons es compleixin o no certes condicions. És, juntament amb els bucles que veuràs a la lliçó següent, la base de qualsevol lògica de negoci real.

Contingut

  1. La sentència if
  2. else if i else: encadenar condicions
  3. Operadors de comparació
  4. Operadors lògics: &&, ||, !
  5. L'operador ternari ?:
  6. Imbricació de condicionals i bones pràctiques
  7. Coalescència nul·la en condicions: ?? i ??=
  8. Aplicació completa: es pot deixar el llibre?

  1. La sentència if

La sentència if avalua una expressió booleana (true o false) i executa un bloc de codi únicament si aquesta expressió és true.

bool disponible = true;

if (disponible)
{
    Console.WriteLine("El llibre esta disponible per prestar.");
}

Punts clau:

  • La condició va entre parèntesis ( ) i ha de ser una expressió de tipus bool.
  • El bloc de codi va entre claus { }. Si el bloc té una única instrucció, les claus són opcionals, però es recomana mantenir-les sempre: millora la llegibilitat i evita errors quan més endavant s'afegeix una segona línia al bloc.
  • Si la condició és false, el bloc simplement se salta i el programa continua per la instrucció següent.
int pagines = 350;

// Sense claus: funciona, pero no es recomanable
if (pagines > 300)
    Console.WriteLine("Es un llibre extens.");

  1. else if i else: encadenar condicions

Quan hi ha més de dos camins possibles, s'encadenen condicions amb else if, i es reserva else per al cas "en qualsevol altra situació".

int prestecsActiusSoci = 3;

if (prestecsActiusSoci == 0)
{
    Console.WriteLine("El soci no te prestecs actius.");
}
else if (prestecsActiusSoci < 5)
{
    Console.WriteLine("El soci te marge per demanar mes llibres.");
}
else
{
    Console.WriteLine("El soci ha arribat al limit de prestecs.");
}

El flux s'avalua de dalt a baix i s'atura en la primera condició que sigui true. Això és important: encara que prestecsActiusSoci < 5 també seria certa quan val 0, la primera condició (== 0) ja ha capturat aquest cas, així que la resta de blocs else if ni tan sols s'avaluen.

Estructura Quants blocs s'executen? Quan usar-la?
if sol 0 o 1 Una única condició opcional
if/else Sempre 1 Dos camins excloents
if/else if/else Sempre 1 (el primer que compleixi) Diversos camins excloents, ordenats per prioritat

  1. Operadors de comparació

Per construir condicions calen operadors que comparin valors i retornin un bool.

Operador Significat Exemple (pagines = 350) Resultat
== Igual a pagines == 350 true
!= Diferent de pagines != 350 false
> Més gran que pagines > 300 true
< Més petit que pagines < 300 false
>= Més gran o igual que pagines >= 350 true
<= Més petit o igual que pagines <= 349 false

Un error molt habitual entre qui comença és confondre = (assignació) amb == (comparació). if (disponible = true) no compara res: assigna true a disponible i, a més, no compila si disponible no és d'un tipus bool compatible amb aquesta assignació en aquest context. Para sempre atenció a aquest detall.

També es poden comparar cadenes de text amb ==, ja que string sobrecarrega aquest operador per comparar el contingut (i no la referència en memòria):

string titolBuscat = "Rayuela";
string titolCataleg = "Rayuela";

if (titolBuscat == titolCataleg)
{
    Console.WriteLine("Coincidencia trobada al cataleg.");
}

  1. Operadors lògics: &&, ||, !

Quan una decisió depèn de diverses condicions alhora, es combinen amb operadors lògics.

Operador Nom Es compleix quan...
&& I lògic (AND) ambdues condicions són true
|| O lògic (OR) almenys una de les condicions és true
! Negació (NOT) inverteix el valor de la condició
bool disponible = true;
int prestecsActiusSoci = 2;
const int LimitPrestecs = 5;

if (disponible && prestecsActiusSoci < LimitPrestecs)
{
    Console.WriteLine("Prestec autoritzat.");
}
else
{
    Console.WriteLine("Prestec denegat.");
}

Amb ! s'inverteix una condició booleana, cosa que sovint fa el codi més llegible que comparar explícitament amb false:

bool esMoros = false;

if (!esMoros)
{
    Console.WriteLine("El soci no te sancions pendents.");
}

Un detall important de rendiment i de seguretat és el curtcircuit (short-circuit evaluation): a a && b, si a ja és false, C# no arriba a avaluar b perquè el resultat ja està decidit. El mateix passa amb a || b si a ja és true. Això permet escriure condicions segures com la següent, on la segona part només s'avalua si la primera garanteix que no hi haurà un error:

string[] titolsLlibres = { "Cent anys de solitud", "Rayuela", "Ficcions" };
int index = 5;

if (index < titolsLlibres.Length && titolsLlibres[index] == "Rayuela")
{
    Console.WriteLine("Trobat.");
}
else
{
    Console.WriteLine("Index fora de rang o titol diferent.");
}

Si index < titolsLlibres.Length és false (com en aquest cas, amb només 3 elements i un index de valor 5), C# mai arriba a accedir a titolsLlibres[index], evitant així una excepció per índex fora de rang.

  1. L'operador ternari ?:

L'operador ternari condensa un if/else senzill, d'una sola expressió, en una única línia. La seva forma és:

condicio ? valorSiVertader : valorSiFals
bool disponible = true;
string estat = disponible ? "Disponible" : "Prestat";

Console.WriteLine($"Estat del llibre: {estat}");

És equivalent a:

string estat;
if (disponible)
{
    estat = "Disponible";
}
else
{
    estat = "Prestat";
}

El ternari és ideal quan el resultat és un valor simple que s'assignarà o es mostrarà directament. No convé abusar-ne per a lògica complexa ni imbricar diversos ternaris entre si, perquè el codi es torna difícil de llegir:

// Evita aixo: dos ternaris imbricats son dificils de llegir d'un cop d'ull
string categoria = pagines > 500 ? "Extens" : pagines > 200 ? "Mitja" : "Breu";

En aquests casos és preferible un if/else if/else explícit, o el switch que veuràs a la propera lliçó d'aquest mòdul.

  1. Imbricació de condicionals i bones pràctiques

És habitual necessitar una condició dins d'una altra:

bool disponible = true;
int prestecsActiusSoci = 4;
const int LimitPrestecs = 5;

if (disponible)
{
    if (prestecsActiusSoci < LimitPrestecs)
    {
        Console.WriteLine("Prestec autoritzat.");
    }
    else
    {
        Console.WriteLine("El soci ha arribat al seu limit de prestecs.");
    }
}
else
{
    Console.WriteLine("El llibre no esta disponible actualment.");
}

Aquest codi funciona, però quan la imbricació creix (tres, quatre nivells) es torna difícil de seguir. Dues tècniques ajuden a mantenir-lo controlat:

Combinar condicions amb operadors lògics en lloc d'imbricar, quan el resultat final és el mateix:

if (disponible && prestecsActiusSoci < LimitPrestecs)
{
    Console.WriteLine("Prestec autoritzat.");
}
else
{
    Console.WriteLine("Prestec denegat.");
}

Invertir la condició i sortir com abans millor (early return o guard clauses), molt útil dins de mètodes o funcions locals: en lloc d'imbricar el cas "bo" dins de diversos if, es descarten primer els casos que impedeixen continuar.

string AvaluarPrestec(bool disponible, int prestecsActiusSoci, int limitPrestecs)
{
    if (!disponible)
    {
        return "El llibre no esta disponible.";
    }

    if (prestecsActiusSoci >= limitPrestecs)
    {
        return "El soci ha arribat al seu limit de prestecs.";
    }

    return "Prestec autoritzat.";
}

Aquesta segona versió evita la imbricació per complet i cada condició es llegeix de manera independent, cosa que facilita afegir noves regles en el futur (per exemple, comprovar si el soci té sancions pendents) sense reestructurar tot el bloc.

  1. Coalescència nul·la en condicions: ?? i ??=

A la lliçó de variables ja vas veure que un tipus de referència, com string, pot valer null. Els operadors ?? (coalescència nul·la) i ??= (assignació amb coalescència nul·la) són molt útils per prendre decisions quan una dada pot faltar.

?? retorna l'operand esquerre si no és null, o el dret en cas contrari:

string? isbnIntroduit = null;
string isbnAMostrar = isbnIntroduit ?? "ISBN no disponible";

Console.WriteLine(isbnAMostrar); // ISBN no disponible

Això evita haver d'escriure l'equivalent més llarg:

string isbnAMostrar;
if (isbnIntroduit != null)
{
    isbnAMostrar = isbnIntroduit;
}
else
{
    isbnAMostrar = "ISBN no disponible";
}

??= assigna un valor per defecte només si la variable actualment és null, i no fa res si ja té un valor:

string? notaSoci = null;
notaSoci ??= "Sense incidencies registrades";

Console.WriteLine(notaSoci); // Sense incidencies registrades

notaSoci ??= "Aquest text mai s'assigna";
Console.WriteLine(notaSoci); // Continua mostrant: Sense incidencies registrades

Aquests operadors també es combinen directament dins d'una condició if:

string? cercaUsuari = null;

if ((cercaUsuari ?? "").Length > 0)
{
    Console.WriteLine("Cercant: " + cercaUsuari);
}
else
{
    Console.WriteLine("No hi ha cap terme de cerca introduit.");
}

  1. Aplicació completa: es pot deixar el llibre?

Reunim tot l'anterior en un exemple proper al que tindrà BiblioTechConsola: decidir si un llibre es pot deixar segons la seva disponibilitat i el nombre de préstecs actius del soci.

bool llibreDisponible = true;
int prestecsActiusSoci = 4;
const int LimitPrestecsPerSoci = 5;
bool sociSancionat = false;

bool esPotPrestar = llibreDisponible
    && !sociSancionat
    && prestecsActiusSoci < LimitPrestecsPerSoci;

string missatge = esPotPrestar
    ? "Prestec autoritzat: pots lliurar aquest exemplar."
    : "Prestec denegat.";

Console.WriteLine(missatge);

if (!esPotPrestar)
{
    if (!llibreDisponible)
    {
        Console.WriteLine("Motiu: no queden exemplars disponibles.");
    }
    else if (sociSancionat)
    {
        Console.WriteLine("Motiu: el soci te una sancio activa.");
    }
    else
    {
        Console.WriteLine("Motiu: el soci va arribar al limit de prestecs.");
    }
}

Fixa't en el disseny: una única expressió booleana (esPotPrestar) concentra la regla de negoci principal combinant && i !, el ternari decideix el missatge principal, i només si el préstec es denega s'entra en un segon bloc if/else if/else per explicar el motiu exacte. És una estructura molt més mantenible que imbricar els tres if un dins de l'altre.

Errors Comuns i Consells

  • Confondre = amb ==. És l'error més freqüent entre principiants. El compilador de C# sol detectar-ho si els tipus no encaixen, però convé revisar-ho sempre a simple vista.
  • Imbricar massa nivells d'if. Si et trobes amb tres o més nivells d'indentació, gairebé sempre es pot simplificar combinant condicions amb &&/|| o aplicant el patró de sortida anticipada (guard clauses).
  • Oblidar l'else quan realment fa falta. Si una variable ha de tenir sempre un valor assignat, assegura't de cobrir tots els camins possibles.
  • Abusar de l'operador ternari per a lògica complexa o imbricada. Reserva'l per a decisions simples d'un únic valor.
  • No comprovar null abans d'operar sobre una variable de tipus referència. Fes servir ?? per donar un valor per defecte en lloc d'arriscar-te a una excepció NullReferenceException (veuràs les excepcions en detall a l'última lliçó d'aquest mòdul).
  • Comparar cadenes sense tenir en compte majúscules/minúscules quan l'usuari introdueix text lliure. Recorda ToLower() (vist a la lliçó anterior) si vols una comparació que ignori la capitalització.

Exercicis

  1. Declara tres variables: int pagines, bool disponible i int prestecsActiusSoci. Escriu un if/else if/else que mostri per consola:

    • "No disponible" si disponible és false.
    • "Prestec llarg (mes de 400 pagines)" si esta disponible i pagines > 400.
    • "Prestec normal" en qualsevol altre cas en que estigui disponible.
  2. Fent servir l'operador ternari, crea una variable string resultat que contingui "Soci al limit" si prestecsActiusSoci >= 5, o "Soci amb marge" en cas contrari. Mostra el resultat per consola.

  3. Declara string? correuSoci = null;. Fes servir ?? per mostrar per consola el correu si existeix, o el text "Sense correu registrat" si és null. Després fes servir ??= per assignar-li el valor "[email protected]" només si continua sent null, i mostra el valor final.

Solucions

int pagines = 550;
bool disponible = true;
int prestecsActiusSoci = 2;

if (!disponible)
{
    Console.WriteLine("No disponible");
}
else if (pagines > 400)
{
    Console.WriteLine("Prestec llarg (mes de 400 pagines)");
}
else
{
    Console.WriteLine("Prestec normal");
}

Amb pagines = 550 i disponible = true, el resultat mostrat és "Prestec llarg (mes de 400 pagines)". Fixa't que primer es comprova !disponible: així, si el llibre no estigués disponible, ni tan sols s'arribaria a mirar el nombre de pàgines.

int prestecsActiusSoci = 5;
string resultat = prestecsActiusSoci >= 5 ? "Soci al limit" : "Soci amb marge";

Console.WriteLine(resultat);

Amb prestecsActiusSoci = 5, el resultat mostrat és "Soci al limit", ja que la condició >= 5 es compleix exactament al límit.

string? correuSoci = null;

string correuAMostrar = correuSoci ?? "Sense correu registrat";
Console.WriteLine(correuAMostrar); // Sense correu registrat

correuSoci ??= "[email protected]";
Console.WriteLine(correuSoci); // [email protected]

La primera línia no modifica correuSoci: només calcula un valor alternatiu per mostrar-lo. La segona línia (??=) sí que modifica la variable, assignant-li el valor per defecte perquè en aquell moment continuava sent null.

Conclusió

En aquesta lliçó has après a prendre decisions al teu codi amb if/else if/else, a construir condicions amb operadors de comparació i lògics, a simplificar assignacions senzilles amb l'operador ternari ?:, a mantenir la imbricació sota control combinant condicions o aplicant sortides anticipades, i a fer servir ??/??= per treballar amb dades que poden faltar. Amb això, BiblioTechConsola ja pot decidir si un préstec és vàlid segons diverses regles de negoci alhora.

Tanmateix, prendre una única decisió no és suficient quan cal repetir una acció moltes vegades: recórrer tot el catàleg de llibres, comptar quants estan disponibles, o buscar-ne un pel títol fins a trobar-lo. A la lliçó següent, Bucles, aprendràs a repetir instruccions amb for, while, do-while i foreach, i a controlar aquesta repetició amb break i continue.

Curs de Programació en C#

Mòdul 1: Introducció al C#

Mòdul 2: Estructures de Control

Mòdul 3: Programació Orientada a Objectes

Mòdul 4: Conceptes Avançats de C#

Mòdul 5: Treballant amb Dades

Mòdul 6: Temes Avançats

Mòdul 7: Construcció d'Aplicacions

Mòdul 8: Bones Pràctiques i Patrons de Disseny

Mòdul 9: Projecte Final

© Copyright 2026. Tots els drets reservats