Switch expressions 讓 C# 的 switch statement 更方便了。
開發環境 Visual Studio 2019 Preview 4 (16.0.0 Preview 4)
框架 .NET Core 3.0.100-preview3-010431
編譯器 C# 8.0 beta
前幾天的文章『C# 8.0 搶先看 -- Recursive patterns』所提到的 recursive patterns 已經很狂了,switch expressions 這個新的特性也不遑多讓,
switch statement 的改變歷史應該是從 7.0 開始的,在 C# 6 以前的時代 switch statement 是個很單純的傢伙,因為比對運算式的限制很多,基本上每個 case statement 都是互斥的;到了 C# 7.0,微軟解除了對於比對運算式的限制,在 Microsoft Docs 上有這個一句話 『 Starting with C# 7.0, the match expression can be any non-null expression. 』,也就是說任何非 null 的運算式都可以成為 switch 的比對運算式,這使得 pattern matching 可以應用在 switch statement;另外在 case statement 已經解除互斥的限制,又加上了 when clause(子句) 的語法,這些特性使得在 C# 7.0 後 switch 的應用更為靈活。
到了 C# 8.0,又添加上可以使用 expression body (運算式主體),創造出更簡潔的 switch case 語法,不囉嗦,先來看第一個範例。
先設定兩個資料型別,分別是矩形與圓形:
class Rectangle
{
public double Width { get; set; }
public double Height { get; set; }
}
class Circle
{
public double Radius { get; set; }
}
使用以上兩個型別建立一個 List<object> 集合,循序取出這個集合的物件並且回傳其面積,若不是 Rectangle 或 Circle 的執行個體,則回傳 -1:
class Program
{
static void Main(string[] args)
{
foreach (var shape in GetObjects())
{
Console.WriteLine(GetArea(shape));
}
}
/// <summary>
/// 依據不同形狀,設定不同面積計算方式
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
static double GetArea(object shape)
{
return shape switch
{
Rectangle r => r.Width * r.Height,
Circle c => Math.Pow(c.Radius, 2) * Math.P
_ => -1,
};
}
/// <summary>
/// 建立物件的集合
/// </summary>
/// <returns></returns>
static List<object> GetObjects() =>
new List<object>
{
new Rectangle { Width = 5, Height =5 },
new Rectangle { Width = 15, Height =5 },
new Circle { Radius = 6 },
new Rectangle { Width = 5, Height =5 },
new Circle { Radius = 10 },
};
}
重點在 GetArea 這個 method,C# 8.0 為 case statement 引進了 expression-bodied ,而且這個把 switch 的條件式 (就是 shape) 的順序換了一下,這個更換順序也使得整個 switch 區塊可以應用 expression-bodied method,於是就讓程式碼可以更短一些,如下:
static double GetArea(object shape) => shape switch
{
Rectangle r => r.Width * r.Height,
Circle c => Math.Pow(c.Radius, 2) * Math.PI,
_ => -1,
};
若是在 C# 7.x 的版本上要使用以下的寫法 :
static double GetArea(object shape)
{
switch (shape)
{
case Rectangle r:
return r.Width * r.Height;
case Circle c:
return Math.Pow(c.Radius, 2) * Math.PI;
default:
return -1;
}
}
註:如果是 C# 6 及其以下的版本,硬要用 switch statement 解這個問題就會寫出極為醜陋又不穩固的程式碼了,在這個情況下,用 if statement 都來得比 switch statement 好。
此篇先介紹基本語法,下一篇來聊其他的相關應用變化。