Patterns
Forms that compile (26)
Section titled “Forms that compile (26)”Forms that don’t compile (6)
Section titled “Forms that don’t compile (6)”| Syntax | Description | Error | Reason | Instead |
|---|---|---|---|---|
p is (1, 2) | Deconstruct and match by position | TUKI0001 | not yet | Match by member value ({ Item1: 1 }) |
value is int(型引数の値に対して) | Apply a pattern to a type argument’s value | TUKI0001 | not yet | Rewrite it without using a type parameter |
case int n when n > 3: | Attach a condition to a case | TUKI0099 | not yet | In a switch expression, a case can carry a condition (k switch { int n when n > 3 => … }) |
s switch { Line l when … => … } | Attach a condition to a union type pattern | TUKI0001 | not yet | Move the condition into the case body, or split the case without when |
n switch { 1 => 10, 2 => 20 } | Omit the default case (int) | TUKI0001 | by design | Add _ =>. It can only be omitted for a union. |
m switch { Mode.A => 1, Mode.B => 2 } | Omit the default case (enum) | TUKI0001 | by design | Can’t be omitted even if the cases cover every value |
You can only omit the default case for a union. For int and enums, a _ => case is required even if the cases cover every value. |
when can only be written on a case in a switch expression. Adding when to a case label produces TUKI0099.
Branching on constants
Section titled “Branching on constants”Branch with a statement
Section titled “Branch with a statement”using UnityEngine;using Tsukimi;
public class PatSwitchStatement : TsukimiBehaviour{ void Start() { int n = 1; switch (n) { case 1: Debug.Log(10); break; default: Debug.Log(0); break; } }}
// Output// 10Branch with a statement (numbers)
Section titled “Branch with a statement (numbers)”using UnityEngine;using Tsukimi;
public class IsoSwStmtConst : TsukimiBehaviour{ void Start() { int k = 1; switch (k) { case 1: Debug.Log(1); break; default: Debug.Log(0); break; } // => 1 }}Branch with an expression
Section titled “Branch with an expression”A switch expression evaluates to the value of the matching case. Matching an int requires a _ => case.
using UnityEngine;using Tsukimi;
public class PatDiscardArm : TsukimiBehaviour{ void Start() { int n = 1; int r = n switch { 1 => 10, _ => 0 }; Debug.Log(r); // => 10 }}Branch on an enum
Section titled “Branch on an enum”You can write enum constants as cases. Even if the cases cover every value, the _ => case can’t be omitted.
using UnityEngine;using Tsukimi;
public enum Mode { A, B }
public class PatEnumConstant : TsukimiBehaviour{ void Start() { Mode m = Mode.A; int r = m switch { Mode.A => 1, _ => 0 }; Debug.Log(r); // => 1 }}Branch on a string
Section titled “Branch on a string”using UnityEngine;using Tsukimi;
public class PatStringConstant : TsukimiBehaviour{ void Start() { string s = "a"; int r = s switch { "a" => 1, _ => 0 }; Debug.Log(r); // => 1 }}Dispatching by type
Section titled “Dispatching by type”Checking the type
Section titled “Checking the type”Writing a type on the right of is only works for union and interface values.
using UnityEngine;using Tsukimi;
public abstract record Shape;public record Dot : Shape;public record Line(int Len) : Shape;
public class IsoIsTypeUnion : TsukimiBehaviour{ void Start() { Shape s = new Dot(); bool b = s is Dot; Debug.Log(b); // => true }}Checking the type and binding
Section titled “Checking the type and binding”using UnityEngine;using Tsukimi;
public abstract record Shape;public record Dot : Shape;public record Line(int Len) : Shape;
public class PtDeclaration : TsukimiBehaviour{ void Start() { Shape s = new Line(3); if (s is Line l) { Debug.Log(l.Len); } // => 3 }}Type in a case label
Section titled “Type in a case label”You can write a type in a case label too. This branches on a union value by type.
using UnityEngine;using Tsukimi;
public abstract record Shape;public record Dot : Shape;public record Line(int Len) : Shape;
public class PtTypeCase : TsukimiBehaviour{ void Start() { Shape s = new Dot(); switch (s) { case Dot: Debug.Log(0); break; default: Debug.Log(1); break; } // => 0 }}Exhaustive union cases
Section titled “Exhaustive union cases”Writing all the union’s cases lets you omit the _ => case.
using UnityEngine;using Tsukimi;
public abstract record Shape;public record Dot : Shape;public record Line(int Len) : Shape;
public class PtExhaustiveUnion : TsukimiBehaviour{ void Start() { Shape s = new Dot(); int v = s switch { Dot d => 0, Line l => l.Len }; Debug.Log(v); // => 0 }}Matching on value conditions
Section titled “Matching on value conditions”Matching a constant
Section titled “Matching a constant”using UnityEngine;using Tsukimi;
public class IsoIsConst : TsukimiBehaviour{ void Start() { int k = 1; bool b = k is 1; Debug.Log(b); // => true }}Matching against null
Section titled “Matching against null”using UnityEngine;using Tsukimi;
public class PtConstNull : TsukimiBehaviour{ void Start() { string s = null; if (s is null) { Debug.Log(1); } // => 1 }}Matching a string constant
Section titled “Matching a string constant”using UnityEngine;using Tsukimi;
public class PtConstString : TsukimiBehaviour{ void Start() { string s = "a"; if (s is "a") { Debug.Log(1); } // => 1 }}Matching an enum constant
Section titled “Matching an enum constant”using UnityEngine;using Tsukimi;
public enum Mode { Off, On }public class PtConstEnum : TsukimiBehaviour{ void Start() { Mode m = Mode.On; if (m is Mode.On) { Debug.Log(1); } // => 1 }}Relational matching
Section titled “Relational matching”using UnityEngine;using Tsukimi;
public class PtRelational : TsukimiBehaviour{ void Start() { int k = 1; if (k is < 30) { Debug.Log(1); } // => 1 }}Combining conditions (and)
Section titled “Combining conditions (and)”using UnityEngine;using Tsukimi;
public class PtAnd : TsukimiBehaviour{ void Start() { int k = 1; if (k is >= 0 and <= 100) { Debug.Log(1); } // => 1 }}How many times the receiver is evaluated
Section titled “How many times the receiver is evaluated”The left side of is is evaluated only once. Even with two conditions, Next() is called once.
using UnityEngine;using Tsukimi;
public class PtAndOnce : TsukimiBehaviour{ int Next() { Debug.Log(9); // => 9 return 1; }
void Start() { if (Next() is >= 0 and <= 100) { Debug.Log(1); } // => 1 }}Combining conditions (or)
Section titled “Combining conditions (or)”using UnityEngine;using Tsukimi;
public class PtOr : TsukimiBehaviour{ void Start() { int k = 3; if (k is 3 or 4) { Debug.Log(1); } // => 1 }}Negation
Section titled “Negation”using UnityEngine;using Tsukimi;
public class PtNot : TsukimiBehaviour{ void Start() { string s = "a"; if (s is not null) { Debug.Log(1); } // => 1 }}Precedence with parentheses
Section titled “Precedence with parentheses”using UnityEngine;using Tsukimi;
public class PtParen : TsukimiBehaviour{ void Start() { int k = 1; if (k is int and (< 0 or > 100)) { Debug.Log(1); } }}A binding that always matches
Section titled “A binding that always matches”using UnityEngine;using Tsukimi;
public class PtVar : TsukimiBehaviour{ void Start() { int k = 1; if (k is var x) { Debug.Log(x); } // => 1 }}Matching a member value
Section titled “Matching a member value”Inside { }, write the member name and the value to match. Only a struct or record you declared yourself can go on the left.
using UnityEngine;using Tsukimi;
public struct Holder { public int V { get; set; } }public class PtProperty : TsukimiBehaviour{ void Start() { Holder h = new Holder(); if (h is { V: 1 }) { Debug.Log(1); } }}Matching a nested member value
Section titled “Matching a nested member value”using UnityEngine;using Tsukimi;
public struct Holder { public int V { get; set; } }public class PtNested : TsukimiBehaviour{ void Start() { Holder h = new Holder(); if (h is { V: > 0 }) { Debug.Log(1); } }}Conditions on switch cases
Section titled “Conditions on switch cases”Relational case
Section titled “Relational case”using UnityEngine;using Tsukimi;
public class IsoSwExprRel : TsukimiBehaviour{ void Start() { int k = 1; int v = k switch { < 30 => 1, _ => 0 }; Debug.Log(v); // => 1 }}Case with or
Section titled “Case with or”using UnityEngine;using Tsukimi;
public class IsoSwExprOr : TsukimiBehaviour{ void Start() { int k = 3; int v = k switch { 3 or 4 => 1, _ => 0 }; Debug.Log(v); // => 1 }}Case condition (when)
Section titled “Case condition (when)”using UnityEngine;using Tsukimi;
public class IsoSwExprWhen : TsukimiBehaviour{ void Start() { int k = 5; int v = k switch { int n when n > 3 => n, _ => 0 }; Debug.Log(v); // => 5 }}Condition after binding
Section titled “Condition after binding”using UnityEngine;using Tsukimi;
public class R_wc : TsukimiBehaviour{ void Start() { int n = 1; int r = n switch { var v when v > 0 => 10, _ => 0 }; Debug.Log(r); // => 10 }}