### C# 8.0 搶先看 -- Switch expressions (2)

1. 配合 when 的使用

``````  class Program
{
static void Main(string[] args)
{
foreach (var shape in GetObjects())
{
var result = GetArea(shape);
if (result != null)
{
Console.WriteLine(result);
}
else
{
Console.WriteLine("this is null");
}
}
}

/// <summary>
/// 依據不同形狀，並且寬高/半徑必須大於零，設定不同面積計算方式
/// 在 vs2019 preview 4.1 svc1 的時候，不能直接回傳 null，必須是 new double?() 或 default(double?)
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
static double? GetArea(object shape) => shape switch
{
Rectangle r when r.Width > 0 && r.Height > 0 => r.Width * r.Height,
_ => default(double?),
};

/// <summary>
/// 建立物件的集合
/// </summary>
/// <returns></returns>
static List<object> GetObjects() =>
new List<object>
{
new Rectangle {Width = 0, Height = 10},
new Rectangle {Width = 10, Height = -1},
new Circle { Radius = 0 },
new Circle { Radius = -2 },
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 },
};
}

class Rectangle
{
public double Width { get; set; }
public double Height { get; set; }
}

class Circle
{
public double Radius { get; set; }
}
``````

``  _ => null``

`````` _ => default(double?)
_ => new double?()``````

2. tuple pattern

Tuple Pattern 適用於處理多值輸入的 switch statement 情境，簡單說就是先用個 ValueTuple 把參數們都塞進去，讓這個 ValueTuple 成為 switch statement 的判斷條件。比方以下農夫過河的例子，Eat method 傳入兩個 Role，狼會吃羊、羊會吃大白菜， 只要傳入的參數符合 『狼，羊』、『羊，狼』、『羊，大白菜』、『大白菜，羊』就回傳 true，其餘狀況則回傳 false。內容我有點偷懶， List 的內容型別也用了 ValueTuple<Role,Role> 所以程式碼看起來有點不太合理，不過這無關緊要，重點是 Eat method。

`````` class Program
{
static void Main(string[] args)
{
foreach (var item in CreateList ())
{
Console.WriteLine(Eat(item.Item1 , item.Item2));
}
}

static List<ValueTuple<Role, Role>> CreateList() => new List<(Role, Role)>
{
(Role.狼, Role.羊),
(Role.狼, Role.大白菜),
(Role.狼, Role.農夫),
(Role.農夫, Role.羊),
(Role.農夫, Role.大白菜),
(Role.農夫, Role.狼),
(Role.羊, Role.農夫),
(Role.羊, Role.大白菜),
(Role.羊, Role.狼),
};

static bool Eat(Role role1, Role role2) => (role1, role2) switch
{
(Role.狼, Role.羊) => true,
(Role.羊, Role.狼) => true,
(Role.羊, Role.大白菜) => true,
(Role.大白菜, Role.羊) => true,
(_, _) => false
};
}

public enum Role
{
農夫,
狼,
羊,
大白菜
}
``````