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

3. position pattern

Position pattern 其實和 ValueTuple 也有點關係， 主要是應用在具有 Deconstruct 的型別。這個範例先假設有一個 Expression class，其內容包含了一個 string 型別的運算元以及兩個 double 型別的運算子 (註：為了讓運算元可以有例外的情形，所以我們很不合理的用了 string 型別來表示)；而且為這個類別加入一個  Deconstruct method (解構元組方法)。

 class Expression
{
public Expression(string operand, double x, double y)
{
Operand = operand;
X = x;
Y = y;
}
public string Operand { get; }
public double X { get;  }
public double Y { get; }

public void Deconstruct(out string operand, out double x, out double y)
{
operand = Operand;
x = X;
y = Y;
}
}



 class Program
{
static void Main(string[] args)
{
foreach (var item in CreateList())
{
try
{
Console.WriteLine(Calculate(item));
}
catch (ArgumentException ex )
{
Console.WriteLine(ex.Message);
}
}
}

static double Calculate(Expression expression) => expression switch
{
("+", var x, var y) => x + y,
("-", var x, var y) => x - y,
("*", var x, var y) => x * y,
("/", _, 0) => double.NaN,
("/", var x, var y) => x / y,
(_, _, _) => throw new ArgumentException("Operand should be one of +,-,*,/")
};

static List<Expression> CreateList() =>
new List<Expression>
{
new Expression ("+", 1, 2.3),
new Expression ("-", 14.5, 0.1),
new Expression ("*", 8, 1.5),
new Expression ("/", 9, 2),
new Expression ("/", 10, 0),
new Expression ("NotOperand", 10, 10),
};
}


(string s, double x, double y)  = expression;
4. property pattern

property pattern 顧名思義就是靠 proeprty 決定條件是否符合，延續使用上一個計算式的例子，但是將 Descontruct method 移除。

 class Expression
{
public Expression(string operand, double x, double y)
{
Operand = operand;
X = x;
Y = y;
}
public string Operand { get; }
public double X { get; }
public double Y { get; }
}


Calculate method 應用 property pattern：

 class Program
{
static void Main(string[] args)
{

foreach (var item in CreateList())
{
try
{
Console.WriteLine(Calculate(item));
}
catch (ArgumentException ex)
{
Console.WriteLine(ex.Message);
}
}
}

static double Calculate(Expression expression) => expression switch
{
{ Operand: "+", X: var x, Y: var y } => x + y,
{ Operand: "-", X: var x, Y: var y } => x - y,
{ Operand: "*", X: var x, Y: var y } => x * y,
{ Operand: "/", Y: 0 } => double.NaN,
{ Operand: "/", X: var x, Y: var y } => x / y,
{ Operand: _ } => throw new ArgumentException("Operand should be one of +,-,*,/")
};

static List<Expression> CreateList() =>
new List<Expression>
{
new Expression ("+", 1, 2.3),
new Expression ("-", 14.5, 0.1),
new Expression ("*", 8, 1.5),
new Expression ("/", 9, 2),
new Expression ("/", 10, 0),
new Expression ("NotOperand", 10, 10),
};
}



Switch expressions 就暫時介紹到此，這三集的範例程式碼在此 SwitchExpressionSamples