WORDS
C# 7: Mönstermatchning med is
och switch
C# är ett programmeringsspråk som kontinuerligt tar beprövade idéer från andra språk. En sådan idé är mönstermatchning (eng. pattern matching) från funktionella programmeringsspråk. Det är ett alternativ till objektorienteringens arv, där man med hjälp av virtual
och override
väljer implementation baserat på objektets typ. Genom hela artikeln kommer vi använda areaberäkning som exempel.
Exempel: beräkna area
Låt säga att vi har ett par olika sorts former, rektanglar och cirklar, och vill beräkna deras areor. Givet en äldre version av C#, skulle implementationen skulle kunna se ut såhär.
public static double ComputeArea(object shape)
{
if (shape is Rectangle)
{
var r = (Rectangle)shape;
return r.Length * r.Height;
}
else if (shape is Circle)
{
var c = (Circle)shape;
return c.Radius * c.Radius * Math.PI;
}
else if (shape is Triangle)
{
var t = (Triangle)shape;
return t.Base * t.Height / 2;
}
throw new ArgumentException("Unknown shape");
}
Deklarera variabler med is
Numera kan man deklarera en variabel direkt i is
-uttrycket, så det finns ingen anledning att cast:a inputen.
public static double ComputeArea2(object shape)
{
if (shape is Rectangle r)
return r.Length * r.Height;
else if (shape is Circle c)
return c.Radius * c.Radius * Math.PI;
else if (shape is Triangle t)
return t.Base * t.Height / 2;
throw new ArgumentException("Unknown shape");
}
switch
med typer
Man har historiskt bara kunnat använda switch
med konstanta mönster, men nu kan man också matcha mot typer.
public static double ComputeArea3(object shape)
{
switch (shape)
{
case Rectangle r:
return r.Length * r.Height;
case Circle c:
return c.Radius * c.Radius * Math.PI;
case Triangle t:
return t.Base * t.Height / 2;
default:
throw new ArgumentException("Unknown shape");
}
}
switch
med when
I C# 7.0 har man utökat switch
till att bli så flexibel, att den kan ersätta många if
-else if
-else
-kedjor.
public static double ComputeArea4(object shape)
{
switch (shape)
{
case Rectangle r when r.Length == 0 || r.Height == 0:
case Circle c when c.Radius == 0:
case Triangle t when t.Base == 0 || t.Height == 0:
return 0;
case Rectangle r:
return r.Length * r.Height;
case Circle c:
return c.Radius * c.Radius * Math.PI;
case Triangle t:
return t.Base * t.Height / 2;
default:
throw new ArgumentException("Unknown shape");
}
}
Vidare läsning
Microsofts dokumentation om mönstermatchning går in i detalj i hur kompilatorn tolkar olika användningar.