式
書ける形(38)
Section titled “書ける形(38)”| 書き方 | 説明 |
|---|---|
+ - * / % | 四則と剰余 |
-b(byte) | 単項演算子での int への昇格 |
int + long → long | 二項演算子での型の統一 |
-a / !b | 符号の反転と論理否定 |
++ -- | 増減 |
+= -= *= /= %= | 複合代入 |
a = b = 3 | 連続した代入 |
< > <= >= == != | 数値の比較 |
(a, b) == (c, d) | タプルどうしの比較 |
&& || | 短絡評価 |
& | ^ ~ | ビットの論理演算 |
(a << 3) >> 1 | ビットのシフト |
a << (int)n | シフト量への変数の指定 |
"a" + "b" + 1 | 文字列の連結 |
a == "x" | 文字列の内容の比較 |
$"n={n}" | 値の埋め込み |
$"{f:F2}" | 埋め込みの書式指定 |
$"{n,5}" | 埋め込みの幅指定 |
s ?? "x" | null のときの既定値 |
s ??= "x" | null のときだけの代入 |
target?.Rotate(...) | null 条件の呼び出し |
target?.name | null 条件のメンバ参照 |
(1 + 2) * 3 | 括弧 |
int.MaxValue | 静的メンバへの参照 |
this.gameObject | 自分自身への参照 |
(x: 1, y: 2) | 名前を付けたタプル |
new Point { X = 1 } | オブジェクト初期化子 |
new[] { 1, 2 } | 要素からの配列型の推論 |
new int[2, 3] | 2 次元の配列の生成 |
default(int) | 型の既定値 |
s! | null 免除 |
checked(1 + 2) | 式単位の checked |
checked { ... } | ブロック単位の checked |
unchecked(1 + 2) | 式単位の unchecked |
unchecked { ... } | ブロック単位の unchecked |
(int a, int b) = Pair(); | タプルの分解 |
nameof(Start) | 名前の文字列化 |
typeof(int) | 型そのものの取得 |
書けない形(11)
Section titled “書けない形(11)”| 書き方 | 説明 | エラー | 理由 | 代わりに |
|---|---|---|---|---|
(a, b) == (c, d)(要素の型が違うタプル) | 型の違うタプルどうしを比べる | TUKI0099 | 未実装 | 要素ごとに変換してから比べる |
new { X = 1 } | 名前の無い型を作る | TUKI0001 | 設計 | 名前を付けたタプルか struct で書く |
new GridCell[2, 3](自分で宣言した型) | 自分で宣言した型を 2 次元に並べる | TUKI0001 | 未実装 | 1 次元の配列にするか、ジャグ配列(配列の配列)にする |
new List<int> { 1, 2 } | List を作りながら詰める | TUKI0102, TUKI0101 | 環境 | 配列を使う |
new Dictionary<string,int> { ["k"] = 1 } | 添字で作りながら詰める | TUKI0102, TUKI0101 | 環境 | 同上 |
new System.Action(Helper) | デリゲートを作る | TUKI0108 | 環境 | メソッド名を指定して呼び出す |
v => v * 2 | その場で関数を作る | TUKI0108, TUKI0001 | 環境 | メソッドとして書いて名前で呼ぶ |
Cb Handler; Handler = Do; | 関数を値として持つ | TUKI0108, TUKI0001 | 環境 | 直接呼ぶか、呼ぶメソッドの名前を渡す |
a?[0] | null なら添字を取らない | TUKI0001 | 環境 | if で分ける |
target?.childCount | ?. で値型を取る | TUKI0001 | 環境 | null を確かめてから取る |
sizeof(int) | 大きさを取る | TUKI0099 | 環境 | 定数を自分で書く |
?. が書けるかどうかは、返る値の型で決まります。戻り値の無い呼び出しと、参照型を返すメンバ参照は通ります。値型を返す形は通りません。結果が「値か null か」を表す型になり、その型が実行環境に無いためです。 |
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 }}単項演算子での int への昇格
Section titled “単項演算子での int への昇格”using UnityEngine;using Tsukimi;
public class OpUnaryPromo : TsukimiBehaviour{ void Start() { byte b = 1; int a = -b; Debug.Log(a); // => -1 }}二項演算子での型の統一
Section titled “二項演算子での型の統一”using UnityEngine;using Tsukimi;
public class OpBinPromo : TsukimiBehaviour{ void Start() { int a = 1; long b = 2; long c = a + b; Debug.Log(c); // => 3 }}符号の反転と論理否定
Section titled “符号の反転と論理否定”using UnityEngine;using Tsukimi;
public class ExpressionsUnary : TsukimiBehaviour{ void Start() { int a = 1; bool b = false; Debug.Log(-a + (!b ? 1 : 0)); // => 0 }}using UnityEngine;using Tsukimi;
public class ExpressionsIncrement : TsukimiBehaviour{ void Start() { int a = 1; a++; ++a; a--; --a; Debug.Log(a); // => 1 }}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 }}連続した代入
Section titled “連続した代入”using UnityEngine;using Tsukimi;
public class ExpressionsChainedAssign : TsukimiBehaviour{ void Start() { int a = 0; int b = 0; a = b = 3; Debug.Log(a + b); // => 6 }}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 }}タプルどうしの比較
Section titled “タプルどうしの比較”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 }}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 }}ビットの論理演算
Section titled “ビットの論理演算”using UnityEngine;using Tsukimi;
public class ExpressionsBitwise : TsukimiBehaviour{ void Start() { int a = 6; int b = 3; Debug.Log((a & b) | (a ^ b) | ~a); // => -1 }}ビットのシフト
Section titled “ビットのシフト”using UnityEngine;using Tsukimi;
public class ExpressionsShift : TsukimiBehaviour{ void Start() { int a = 1; Debug.Log((a << 3) >> 1); // => 4 }}シフト量への変数の指定
Section titled “シフト量への変数の指定”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 }}文字列の連結
Section titled “文字列の連結”using UnityEngine;using Tsukimi;
public class ExpressionsStringConcat : TsukimiBehaviour{ void Start() { string s = "a" + "b" + 1; Debug.Log(s); // => "ab1" }}文字列の内容の比較
Section titled “文字列の内容の比較”using UnityEngine;using Tsukimi;
public class OpStrEq : TsukimiBehaviour{ void Start() { string a = "x"; Debug.Log(a == "x"); // => true }}値の埋め込み
Section titled “値の埋め込み”using UnityEngine;using Tsukimi;
public class ExpressionsStringInterpolation : TsukimiBehaviour{ void Start() { int n = 1; string s = $"n={n}"; Debug.Log(s); // => "n=1" }}埋め込みの書式指定
Section titled “埋め込みの書式指定”using UnityEngine;using Tsukimi;
public class ExpressionsStringFormatSpec : TsukimiBehaviour{ void Start() { float f = 1.5f; string s = $"{f:F2}"; Debug.Log(s); // => "1.50" }}埋め込みの幅指定
Section titled “埋め込みの幅指定”using UnityEngine;using Tsukimi;
public class PeInterpAlign : TsukimiBehaviour{ void Start() { int n = 1; Debug.Log($"{n,5}"); // => " 1" }}null のときの既定値
Section titled “null のときの既定値”using UnityEngine;using Tsukimi;
public class ExpressionsNullCoalesce : TsukimiBehaviour{ void Start() { string s = null; string r = s ?? "x"; Debug.Log(r); // => "x" }}null のときだけの代入
Section titled “null のときだけの代入”using UnityEngine;using Tsukimi;
public class ExpressionsNullCoalesceAssign : TsukimiBehaviour{ void Start() { string s = null; s ??= "x"; Debug.Log(s); // => "x" }}null 条件の呼び出し
Section titled “null 条件の呼び出し”using UnityEngine;using Tsukimi;
public class ExpressionsNullConditionalVoid : TsukimiBehaviour{ public Transform target;
void Start() { target?.Rotate(Vector3.up); }}null 条件のメンバ参照
Section titled “null 条件のメンバ参照”受け手が null のとき、式全体が null になります。書けるのは、参照型を返す形だけです。
using UnityEngine;using Tsukimi;
public class ExpressionsNullConditionalReference : TsukimiBehaviour{ public Transform target;
void Start() { string s = target?.name; Debug.Log(s); // => null }}using UnityEngine;using Tsukimi;
public class PeParen : TsukimiBehaviour{ void Start() { int a = (1 + 2) * 3; Debug.Log(a); // => 9 }}静的メンバへの参照
Section titled “静的メンバへの参照”using UnityEngine;using Tsukimi;
public class PeStaticMember : TsukimiBehaviour{ void Start() { Debug.Log(int.MaxValue); // => 2147483647 }}自分自身への参照
Section titled “自分自身への参照”using UnityEngine;using Tsukimi;
public class PeThis : TsukimiBehaviour{ void Start() { Debug.Log(this.gameObject.name); }}名前を付けたタプル
Section titled “名前を付けたタプル”using UnityEngine;using Tsukimi;
public class PeTupleNamed : TsukimiBehaviour{ void Start() { (int x, int y) p = (x: 1, y: 2); Debug.Log(p.x); // => 1 }}オブジェクト初期化子
Section titled “オブジェクト初期化子”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 }}要素からの配列型の推論
Section titled “要素からの配列型の推論”using UnityEngine;using Tsukimi;
public class PeArrInferred : TsukimiBehaviour{ void Start() { int[] a = new[] { 1, 2 }; Debug.Log(a.Length); // => 2 }}2 次元の配列の生成
Section titled “2 次元の配列の生成”添字を 2 つ書いて読み書きします。要素の型を覚えておく場所が無いので、読み書きのたびに変換が挟まります。3 次元以上と、生成と同時に値を並べる書き方は通りません。
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 }}using UnityEngine;using Tsukimi;
public class PeDefaultExpr : TsukimiBehaviour{ void Start() { int a = default(int); Debug.Log(a); // => 0 }}null 免除
Section titled “null 免除”! は null 検査の警告を抑えるだけで、実行時には何もしません。
#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"; }}あふれの検査
Section titled “あふれの検査”式単位の checked
Section titled “式単位の checked”using UnityEngine;using Tsukimi;
public class PeCheckedExpr : TsukimiBehaviour{ void Start() { int a = checked(1 + 2); Debug.Log(a); // => 3 }}ブロック単位の checked
Section titled “ブロック単位の checked”ブロックに付けた checked も、あふれを検査しません。実行環境に例外の仕組みが無いためです。
using UnityEngine;using Tsukimi;
public class ExpressionsCheckedBlock : TsukimiBehaviour{ void Start() { int n = 1; checked { n = n + 1; } Debug.Log(n); // => 2 }}式単位の unchecked
Section titled “式単位の unchecked”unchecked は、あふれを検査しないことの明示です。もともと検査されないので、値は変わりません。
using UnityEngine;using Tsukimi;
public class PeUncheckedExpr : TsukimiBehaviour{ void Start() { int a = unchecked(1 + 2); Debug.Log(a); // => 3 }}ブロック単位の unchecked
Section titled “ブロック単位の unchecked”ブロックに付けた unchecked も、値を変えません。
using UnityEngine;using Tsukimi;
public class ExpressionsUncheckedBlock : TsukimiBehaviour{ void Start() { int n = 1; unchecked { n = n + 1; } Debug.Log(n); // => 2 }}タプルの分解
Section titled “タプルの分解”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 }}名前の文字列化
Section titled “名前の文字列化”using UnityEngine;using Tsukimi;
public class ExpressionsNameof : TsukimiBehaviour{ void Start() { Debug.Log(nameof(Start)); // => "Start" }}型そのものの取得
Section titled “型そのものの取得”using UnityEngine;using Tsukimi;
public class ExpressionsTypeof : TsukimiBehaviour{ void Start() { Debug.Log(typeof(int)); // => typeof:SystemInt32 }}