Guard clauses – tidiga utgångar med stil
Ibland är det mest eleganta du kan göra att säga “nej” så tidigt som möjligt. Guard clauses är korta if-satser högst upp i metoden som kastar ut ogiltiga värden innan resten av logiken körs. Resultatet blir kod som är lättare att läsa och svårare att krascha.
TL;DR
- Kontrollera överraskningar direkt i början av metoden.
- Returnera tidigt eller kasta undantag när förutsättningarna inte är uppfyllda.
- Resten av metoden kan anta att värdena är giltiga → mindre indrag, mindre hjärnknut.
Varför guard clauses?
Tänk dig att du ska bjuda in gäster. Du dubbelkollar listan innan du dukar:
public void SendInvitation(Person guest)
{
if (guest is null) throw new ArgumentNullException(nameof(guest));
if (!guest.HasEmail) throw new InvalidOperationException("Gästen saknar e-postadress");
// Från och med här vet vi att gästen finns och har e-post.
EmailService.Send(
to: guest.Email,
subject: "Välkommen till festen!",
body: "Ta med ditt bästa humör."
);
}
Utan guard clauses hade samma metod krävt ett extra block av else eller släpat runt guest! och guest.Email! – svårt att missa en null-check.
Vanliga mönster
1. Validera argument
public Money CreateInvoice(decimal amount)
{
if (amount <= 0)
throw new ArgumentOutOfRangeException(nameof(amount), "Beloppet måste vara större än noll");
return new Money(amount);
}
2. Stoppa när användaren saknar rättighet
public void DeleteOrder(User user, Guid orderId)
{
if (!user.HasPermission(Permissions.DeleteOrder))
return; // alternativt kasta ett undantag beroende på policy
_repository.Remove(orderId);
}
3. Bryt ut tidigt i loopar
foreach (var order in orders)
{
if (order.IsCancelled)
continue; // hoppa direkt till nästa order
Process(order);
}
Tips för snygga guard clauses
- Grupera logiken: Lägg alla guard clauses direkt efter varandra. Då vet alla var spärrarna sitter.
- Beskriv varför: Felmeddelandet ska säga mer än “invalid” – skriv varför värdet är ogiltigt.
- Undvik pyramidkod: Hellre flera tidiga
returnän 4 nivåer avif/else. - Logga viktiga avbrott: Om du returnerar tyst i ett API – logga händelsen så att du kan felsöka senare.
När du bör låta bli
- När alla kontroller kräver dyra databas-anrop. Då kan du vilja packa ihop dem för att undvika extra kostnader.
- När metoden ändå bara är tre rader – fler guard clauses än verklig logik blir överdrivet.
Övningar
- Grön: Skriv om en metod med tre nivåer
if-nesting så att den använder guard clauses. - Gul: Lägg till loggning i dina guard clauses –
logger.LogWarningnär data saknas. - Röd: Implementera guard clauses i en ASP.NET Core-minikontroller. Returnera
BadRequestvid ogiltig modell, annars kör vidare.
Sammanfattning
- Guard clauses håller din kod ren och läsbar.
- De skyddar resten av logiken från ogiltiga värden och sparar dina användare från kryptiska fel.
- Kombinera dem med tydliga felmeddelanden så vet du direkt vad som gick snett.
Dad joke
Varför gillar guard clauses tidiga morgnar?
För att de alltid lämnar rummet innan saker blir stökiga.