Expressions
Forms that compile (38)
Section titled “Forms that compile (38)”Forms that don’t compile (11)
Section titled “Forms that don’t compile (11)”| Syntax | Description | Error | Reason | Instead |
|---|---|---|---|---|
(a, b) == (c, d)(要素の型が違うタプル) | Comparing tuples of different element types | TUKI0099 | not yet | Convert each element before comparing |
new { X = 1 } | Creating an unnamed type | TUKI0001 | by design | Use a named tuple or a struct |
new GridCell[2, 3](自分で宣言した型) | Arranging a self-declared type in 2 dimensions | TUKI0001 | not yet | Use a 1D array or a jagged array (an array of arrays) |
new List<int> { 1, 2 } | Populate a List while creating it | TUKI0102, TUKI0101 | runtime | Use an array |
new Dictionary<string,int> { ["k"] = 1 } | Populate by index while creating it | TUKI0102, TUKI0101 | runtime | Same as above |
new System.Action(Helper) | Creating a delegate | TUKI0108 | runtime | Call by specifying a method name |
v => v * 2 | Creating a function inline | TUKI0108, TUKI0001 | runtime | Write it as a method and call it by name |
Cb Handler; Handler = Do; | Holding a function as a value | TUKI0108, TUKI0001 | runtime | Call it directly, or pass the name of the method to call |
a?[0] | Skip indexing when null | TUKI0001 | runtime | Branch with if |
target?.childCount | Getting a value type with ?. | TUKI0001 | runtime | Check for null before accessing |
sizeof(int) | Getting the size | TUKI0099 | runtime | Write the constant yourself |
Whether ?. compiles depends on the return type. A call with no return value, and member access that returns a reference type, compile. Forms that return a value type don’t compile. The result would be a type meaning “a value or null,” and that type doesn’t exist in the runtime. |
Operators
Section titled “Operators”Arithmetic and remainder
Section titled “Arithmetic and remainder”using UnityEngine;using Tsukimi;
public class ExpressionsArithmetic : TsukimiBehaviour{ void Start() { int a = 7; int b = 2; Debug.Log(a + b - a * b / a % b); // => 9 }}Promotion to int in unary operators
Section titled “Promotion to int in unary operators”using UnityEngine;using Tsukimi;
public class OpUnaryPromo : TsukimiBehaviour{ void Start() { byte b = 1; int a = -b; Debug.Log(a); // => -1 }}Type unification in binary operators
Section titled “Type unification in binary operators”using UnityEngine;using Tsukimi;
public class OpBinPromo : TsukimiBehaviour{ void Start() { int a = 1; long b = 2; long c = a + b; Debug.Log(c); // => 3 }}Sign negation and logical negation
Section titled “Sign negation and logical negation”using UnityEngine;using Tsukimi;
public class ExpressionsUnary : TsukimiBehaviour{ void Start() { int a = 1; bool b = false; Debug.Log(-a + (!b ? 1 : 0)); // => 0 }}Increment and decrement
Section titled “Increment and decrement”using UnityEngine;using Tsukimi;
public class ExpressionsIncrement : TsukimiBehaviour{ void Start() { int a = 1; a++; ++a; a--; --a; Debug.Log(a); // => 1 }}Compound assignment
Section titled “Compound assignment”using UnityEngine;using Tsukimi;
public class ExpressionsCompoundAssign : TsukimiBehaviour{ void Start() { int a = 1; a += 2; a -= 1; a *= 3; a /= 2; a %= 4; Debug.Log(a); // => 3 }}Chained assignment
Section titled “Chained assignment”using UnityEngine;using Tsukimi;
public class ExpressionsChainedAssign : TsukimiBehaviour{ void Start() { int a = 0; int b = 0; a = b = 3; Debug.Log(a + b); // => 6 }}Numeric comparison
Section titled “Numeric comparison”using UnityEngine;using Tsukimi;
public class ExpressionsComparison : TsukimiBehaviour{ void Start() { int a = 1; Debug.Log(a < 2 && a > 0 && a <= 1 && a >= 1 && a == 1 && a != 2); // => true }}Tuple equality
Section titled “Tuple equality”using UnityEngine;using Tsukimi;
public class ExpressionsTupleEquality : TsukimiBehaviour{ void Start() { (int, int) a = (1, 2); (int, int) b = (1, 2); Debug.Log(a == b); // => true }}Short-circuit
Section titled “Short-circuit”using UnityEngine;using Tsukimi;
public class ExpressionsShortCircuit : TsukimiBehaviour{ void Start() { int n = 1; bool b = n > 0 && n < 5; bool c = n < 0 || n > 0; Debug.Log(b && c); // => true }}Bitwise logical operators
Section titled “Bitwise logical operators”using UnityEngine;using Tsukimi;
public class ExpressionsBitwise : TsukimiBehaviour{ void Start() { int a = 6; int b = 3; Debug.Log((a & b) | (a ^ b) | ~a); // => -1 }}Bit shifting
Section titled “Bit shifting”using UnityEngine;using Tsukimi;
public class ExpressionsShift : TsukimiBehaviour{ void Start() { int a = 1; Debug.Log((a << 3) >> 1); // => 4 }}Variable shift amount
Section titled “Variable shift amount”using UnityEngine;using Tsukimi;
public class OpShiftRelaxed : TsukimiBehaviour{ void Start() { int a = 1; long n = 2; int b = a << (int)n; Debug.Log(b); // => 4 }}Strings
Section titled “Strings”String concatenation
Section titled “String concatenation”using UnityEngine;using Tsukimi;
public class ExpressionsStringConcat : TsukimiBehaviour{ void Start() { string s = "a" + "b" + 1; Debug.Log(s); // => "ab1" }}String content comparison
Section titled “String content comparison”using UnityEngine;using Tsukimi;
public class OpStrEq : TsukimiBehaviour{ void Start() { string a = "x"; Debug.Log(a == "x"); // => true }}Value interpolation
Section titled “Value interpolation”using UnityEngine;using Tsukimi;
public class ExpressionsStringInterpolation : TsukimiBehaviour{ void Start() { int n = 1; string s = $"n={n}"; Debug.Log(s); // => "n=1" }}Interpolation format specifier
Section titled “Interpolation format specifier”using UnityEngine;using Tsukimi;
public class ExpressionsStringFormatSpec : TsukimiBehaviour{ void Start() { float f = 1.5f; string s = $"{f:F2}"; Debug.Log(s); // => "1.50" }}Interpolation width specifier
Section titled “Interpolation width specifier”using UnityEngine;using Tsukimi;
public class PeInterpAlign : TsukimiBehaviour{ void Start() { int n = 1; Debug.Log($"{n,5}"); // => " 1" }}Default value when null
Section titled “Default value when null”using UnityEngine;using Tsukimi;
public class ExpressionsNullCoalesce : TsukimiBehaviour{ void Start() { string s = null; string r = s ?? "x"; Debug.Log(r); // => "x" }}Assignment only when null
Section titled “Assignment only when null”using UnityEngine;using Tsukimi;
public class ExpressionsNullCoalesceAssign : TsukimiBehaviour{ void Start() { string s = null; s ??= "x"; Debug.Log(s); // => "x" }}Null-conditional call
Section titled “Null-conditional call”using UnityEngine;using Tsukimi;
public class ExpressionsNullConditionalVoid : TsukimiBehaviour{ public Transform target;
void Start() { target?.Rotate(Vector3.up); }}Null-conditional member access
Section titled “Null-conditional member access”When the receiver is null, the whole expression becomes null. Only forms that return a reference type compile.
using UnityEngine;using Tsukimi;
public class ExpressionsNullConditionalReference : TsukimiBehaviour{ public Transform target;
void Start() { string s = target?.name; Debug.Log(s); // => null }}Primary expressions
Section titled “Primary expressions”Parentheses
Section titled “Parentheses”using UnityEngine;using Tsukimi;
public class PeParen : TsukimiBehaviour{ void Start() { int a = (1 + 2) * 3; Debug.Log(a); // => 9 }}Static member access
Section titled “Static member access”using UnityEngine;using Tsukimi;
public class PeStaticMember : TsukimiBehaviour{ void Start() { Debug.Log(int.MaxValue); // => 2147483647 }}Reference to self
Section titled “Reference to self”using UnityEngine;using Tsukimi;
public class PeThis : TsukimiBehaviour{ void Start() { Debug.Log(this.gameObject.name); }}Named tuple
Section titled “Named tuple”using UnityEngine;using Tsukimi;
public class PeTupleNamed : TsukimiBehaviour{ void Start() { (int x, int y) p = (x: 1, y: 2); Debug.Log(p.x); // => 1 }}Object initializer
Section titled “Object initializer”using UnityEngine;using Tsukimi;
public struct Point { public int X; }public class PeObjInit : TsukimiBehaviour{ void Start() { Point p = new Point { X = 1 }; Debug.Log(p.X); // => 1 }}Array type inference from elements
Section titled “Array type inference from elements”using UnityEngine;using Tsukimi;
public class PeArrInferred : TsukimiBehaviour{ void Start() { int[] a = new[] { 1, 2 }; Debug.Log(a.Length); // => 2 }}Creating a 2D array
Section titled “Creating a 2D array”Read and write with two indices. There’s no place to remember the element type, so a conversion happens on every read and write. Forms with 3 or more dimensions, and forms that lay out values at creation time, don’t compile.
using UnityEngine;using Tsukimi;
public class ExpressionsArrayCreationRank2 : TsukimiBehaviour{ void Start() { int[,] a = new int[2, 3]; a[1, 2] = 7; Debug.Log(a[1, 2]); // => 7 Debug.Log(a.GetLength(1)); // => 3 }}Default value of a type
Section titled “Default value of a type”using UnityEngine;using Tsukimi;
public class PeDefaultExpr : TsukimiBehaviour{ void Start() { int a = default(int); Debug.Log(a); // => 0 }}Null-forgiving operator
Section titled “Null-forgiving operator”! only suppresses the null-check warning. It does nothing at runtime.
#nullable enableusing UnityEngine;using Tsukimi;
public class PeNullForgiving : TsukimiBehaviour{ void Start() { string? s = Get(); string t = s!; Debug.Log(t); // => "a" }
private string? Get() { return "a"; }}Overflow checking
Section titled “Overflow checking”checked as an expression
Section titled “checked as an expression”using UnityEngine;using Tsukimi;
public class PeCheckedExpr : TsukimiBehaviour{ void Start() { int a = checked(1 + 2); Debug.Log(a); // => 3 }}checked as a block
Section titled “checked as a block”checked on a block doesn’t check for overflow either, because the runtime has no exception mechanism.
using UnityEngine;using Tsukimi;
public class ExpressionsCheckedBlock : TsukimiBehaviour{ void Start() { int n = 1; checked { n = n + 1; } Debug.Log(n); // => 2 }}unchecked as an expression
Section titled “unchecked as an expression”unchecked explicitly states that overflow isn’t checked. Since it’s not checked anyway, the value doesn’t change.
using UnityEngine;using Tsukimi;
public class PeUncheckedExpr : TsukimiBehaviour{ void Start() { int a = unchecked(1 + 2); Debug.Log(a); // => 3 }}unchecked as a block
Section titled “unchecked as a block”unchecked on a block doesn’t change the value either.
using UnityEngine;using Tsukimi;
public class ExpressionsUncheckedBlock : TsukimiBehaviour{ void Start() { int n = 1; unchecked { n = n + 1; } Debug.Log(n); // => 2 }}Tuple deconstruction
Section titled “Tuple deconstruction”using UnityEngine;using Tsukimi;
public class ExpressionsTupleDeconstruct : TsukimiBehaviour{ private (int, int) Pair() { return (1, 2); }
void Start() { (int a, int b) = Pair(); Debug.Log(a + b); // => 3 }}Stringifying a name
Section titled “Stringifying a name”using UnityEngine;using Tsukimi;
public class ExpressionsNameof : TsukimiBehaviour{ void Start() { Debug.Log(nameof(Start)); // => "Start" }}Getting the type itself
Section titled “Getting the type itself”using UnityEngine;using Tsukimi;
public class ExpressionsTypeof : TsukimiBehaviour{ void Start() { Debug.Log(typeof(int)); // => typeof:SystemInt32 }}