Hoppa till innehåll

Metoder, parametrar och överlagring

↑

Exemplen är oberoende C#-utdrag för moderna .NET-konsolprojekt, om inget annat anges. Klassdeklarationer och toppnivåkod kan placeras i samma Program.cs-fil, med toppnivåkoden först.

En metod ger namn åt en återanvändbar operation. Signaturen visar vilka argument som krävs och returtypen vad metoden ger tillbaka.

En parameter deklareras av metoden, medan ett argument skickas av anroparen. Använd void när inget returneras och en lämplig returtyp när anroparen behöver ett resultat.

Example.cs
static int Add(int left, int right)
{
return left + right;
}
Console.WriteLine(Add(2, 3)); // 5

En valfri parameter har ett standardvärde och kan utelämnas. Namngivna argument gör anrop tydligare när flera argument har samma typ.

Example.cs
static string Label(string name, int level = 1)
=> $"{name} (level {level})";
Console.WriteLine(Label("Alex"));
Console.WriteLine(Label(level: 3, name: "Sam"));

Metoder kan ha samma namn om parameterlistorna skiljer sig. Endast returtypen räcker inte för att skilja överlagringar åt. Låt överlagringarna betyda samma sak.

Example.cs
Console.WriteLine(NumberMath.Double(4));
Console.WriteLine(NumberMath.Double(1.5));
public static class NumberMath
{
public static int Double(int number) => number * 2;
public static double Double(double number) => number * 2;
}

Fördjupning: en metod är ett kontrakt med anroparen

Section titled “Fördjupning: en metod är ett kontrakt med anroparen”

En parameter är en variabel i metodens deklaration; ett argument är uttrycket som skickas in vid anrop. Returtypen talar om vad anroparen får tillbaka. void betyder att inget värde returneras, inte att metoden inte kan ändra tillstånd. En metod bör ha ett tydligt ansvar och ett namn som beskriver arbetet.

Program.cs
Console.WriteLine(ScoreRules.CalculateBonus(score: 80, multiplier: 1.5)); // 120
public static class ScoreRules
{
public static int CalculateBonus(int score, double multiplier = 1)
{
if (score < 0 || multiplier < 0)
throw new ArgumentOutOfRangeException();
return (int)Math.Round(score * multiplier);
}
}

score och multiplier är parametrar. Värdena 80 och 1.5 är argument och används här med namngiven argumentnotation. Den valfria parametern har ett känt standardvärde och kan utelämnas. Math.Round följer bestämda avrundningsregler som också kan påverka poängberäkningar.

I C# skickas argument normalt by value. Ett int kopieras; för ett klassobjekt kopieras referensen, och metoden kan därför ändra objektet via den kopierade referensen. ref och out gör i stället själva variabeln tillgänglig för metoden och har skilda regler för initiering. out passar exempelvis när en metod ska rapportera lyckad tolkning och det tolkade värdet, som int.TryParse.

Två metoder kan ha samma namn om parameterlistorna skiljer sig. Det är överlagring, inte override. Kompilatorn väljer en passande överlagring utifrån argumenttyper, konverteringar och valfria parametrar. Returtypen ensam räcker inte för att skilja överlagringar och flera lika rimliga numeriska konverteringar kan ge kompileringsfel.

En beräkningsmetod är enklare att testa när den enbart använder sina parametrar och returnerar resultatet. Om den samtidigt skriver en fil, ändrar en statisk räknare eller påverkar globalt speltillstånd finns sidoeffekter som anroparen behöver känna till. Dela gärna upp beräkningar och I/O när det gör designen tydligare; static betyder inte automatiskt att metoden är ren.

Bryt ut en metod när en operation har ett tydligt namn, går att testa separat eller återanvänds.

En void-metod returnerar inget värde. Undvik överlagringar som ger överraskande beteende vid implicita talomvandlingar.

Skriv IsAdult(int age) som returnerar en bool. Anropa den med ett namngivet argument.

Visa ett lösningsförslag

static bool IsAdult(int age) => age >= 18; IsAdult(age: 20);.