Skip to content

Statiska metoder

Statiska variabler är variabler som tillhör klassen och inte en specifik instans av klassen. Vi kan även skapa metoder som är statiska och som tillhör klassen. Dessa kallas statiska metoder .

Vi gör en getmetod för att komma åt WHEELS och eftersom WHEELS är en konstant som tillhör klassen blir getmetoden på WHEELS statisk. Vi lägger alla statiska metoder tillsammans och blandar de inte med de vanliga get- och set-metoderna.

Lägg till en statisk metod i klassen Car
namespace OoGuide.src;
class Car
{
private const int WHEELS = 4;
private static int _carCount = 0;
...
// Static methods
...
public static int GetWheels()
{
return Car.WHEELS;
}
}

Nu testar vi den statiska getmetoden på WHEELS.

Testa den statiska metoden i huvudprogrammet
Console.WriteLine("Antal hjul: " + Car.GetWheels());
// Ger utskriften: Antal hjul: 4

Vi kanske vill utöka vår beskrivning av bilen med informationen om värdet i i klasskonstanten WHEELS och värdet i klassvariabeln _carCount. Då gör vi en statisk metod som skriver ut detta. Vi lägger metoden tillsammans med de tidigare statiska metoderna i Car klassen.

Metoden som vi namnger DescriptionStatic() har inga inparametrar. Vi kollar på hur vi anropar metoden via klassen.

Lägg till en annan statisk metod i klassen Car
...
// Static methods
...
public static void DescriptionStatic()
{
Console.WriteLine($"Bilen har {Car.WHEELS} hjul och är bil nummer {Car._carCount}.");
}
}
Testa även den statiska metoden i huvudprogrammet
...
Car.DescriptionStatic();
// ger utskriften: Bilen har 6 hjul och är bil nummer 0.

Det är inte möjligt att anropa metoder som inte är statiska i en statisk metod. Om vi t.ex försöker anropa Description() (som inte är statisk) i DescriptionStatic() får vi fel.

Testa att använda this i en statiska metod
// i OoGuide/src/Car.cs
...
// Static methods
...
public static void DescriptionStatic()
{
this.Description();
Console.WriteLine($"Bilen har {Car.WHEELS} hjul och är bil nummer {Car._carCount}.");
}
}

När vi försöker köra får vi:

Kompileringsfel i huvudprogrammet när vi har this i en statisk metod
...
Car.DescriptionStatic();
// ger kompileringsfelet: error CS0026: Keyword 'this' is not valid in a static property,
// static method, or static field initializer

Vi får alltså inte använda this (som representerar anropande instans) i en statisk metod. Ta bort raden med this.Description() i DescriptionStatic() och testkör igen.

Men vad händer om vi skapar ett bilobjekt och försöker anropa den statiska metoden på det?

Kompileringsfel i huvudprogrammet när vi anropar en statisk metod på ett objekt
...
Car bmw = new Car("BMW", 100000);
bmw.DescriptionStatic();
// ger kompileringsfel: error CS0176: Member 'Car.DescriptionStatic()' cannot be accessed
// with an instance reference; qualify it with a type name instead

Detta felet får vi för att vi anropar en statisk metod från en instans av klassen. En statisk metod anropas från klassen, i detta fallet klassen Car.

Vi anropar både Description() (som är en instansmetod/medlemsmetod) och DescriptionStatic() (som är en klassmetod).

Nu använder vi metoderna på rätt sätt i huvudprogrammet
...
Car bmw = new Car("BMW", 100000);
bmw.Description(); // instansmetod anropas på instansen (objektet) bmw
Car.DescriptionStatic(); // statisk metod anropas på klassen Car
// ger utskriften:
// Bilen är en BMW och kostar 100000 kr.
// Bilen har 6 hjul och är bil nummer 1.

Nu har vi testat en statisk metod och sett hur den anropas.

Lägg till en statisk metod för beräkning som är relevant för instanser av klassen

Section titled “Lägg till en statisk metod för beräkning som är relevant för instanser av klassen”

Vi lägger till en statisk metod som gäller för hela klassen. Den använder inte de statiska klassvariablerna men beräkningen som görs ska gälla för alla instanser av klassen och därför gör vi metoden statisk.

Man brukar säga att en bil förlorar 1/3 av sitt värde när den lämnar bilfirman. Vi skapar därför en statisk metod som utför denna beräkning och lägger den bland de statiska metoderna:

Lägg till en statisk metod som räknar ner priset i klassen Car
...
// Static methods
...
public static int CalculatePriceReduction(int price)
{
return (int)(price * 0.66); // type cast double from calculation to int
}
}

Metoden CalculatePriceReduction() har priset som inparameter och returnerar ett heltal som är det nya reducerade priset. Vid beräkningen blir priset ett decimaltal som vi typomvandlar, castar, till ett heltal med hjälp av (int). Nu testar vi att anropa metoden:

Testkör den statiska metoden i huvudprogrammet
...
Console.WriteLine($"Bilens nya värde: {Car.CalculatePriceReduction(bmw.GetPrice())} kr.");
// ger utskriften: Bilens nya värde: 66000 kr.

Vi hämtar priset på vår bmw (Car-objekt) med getmetoden och använder det som inparameter till den statiska metoden CalculatePriceReduction(…). Den statiska metoden anropas, som tidigare, med klassens namn följt av en punkt och därefter namnet på metoden.

Image description
Bild: Klassdiagram över Car med den statisk metoden CalculatePriceReduction

Vi lägger utskrifterna från detta kapitel i samma funktion som vi gjorde i förra kapitlet. Nu ser det ut så här:

Strukturera koden genom att lägga den i en metod som anropas i Program.cs
...
static void TestingStaticMethodPrintouts()
{
Console.WriteLine("Antal hjul: " + Car.GetWheels());
Car.SetWheels(6);
Console.WriteLine("Antal hjul (ny): " + Car.GetWheels());
Car bmw = new Car("BMW", 100000);
bmw.Description();
Car.DescriptionStatic();
Console.WriteLine("Prisreduktion: " + Car.CalculatePriceReduction(bmw.GetPrice()));
}
TestingStaticMethodPrintouts(bmw);

När vi inte vill använda metoden TestingStaticMethodPrintouts kommenterar vi bort den.