メンバ
書ける形(43)
Section titled “書ける形(43)”| 書き方 | 説明 |
|---|---|
private int count; | フィールド |
private int count = 5; | 宣言と同時の代入 |
private const int Max = 10; | 定数 |
private static int Count; | 静的フィールド |
private static readonly int Max = 10; | 静的な読み取り専用フィールド |
private void Do() | メソッドの宣言 |
private int Get() | 戻り値のあるメソッド |
private int Add(int a, int b) | 引数のあるメソッド |
int Add(int a, int b = 2) | 既定の引数 |
Add(b: 2, a: 1) | 名前つき引数 |
Add(int, int) / Add(float, float) | オーバーロード |
private int Twice(int n) => n * 2; | 式形式のメソッド |
private static int Zero() | 静的メソッド |
public int Value { get; set; } | 自動プロパティ |
public int Doubled { get { return n * 2; } } | 計算するプロパティ |
{ get; private set; } | 取得と設定で異なる可視性 |
{ get; set; } = 1; | プロパティの初期値 |
{ get; } | 取得だけの自動プロパティ |
{ get; init; } | init アクセサ |
[field: SerializeField] | 裏のフィールドへの属性 |
public virtual int V { get { … } } | 仮想プロパティ |
public int this[int i] | 添字 |
this[0] = 3; | 添字への書き込み |
public event System.Action Fired; | event の宣言 |
event … { add { } remove { } } | 購読の受け口の記述 |
~C() { } | ファイナライザ |
private volatile int V; | volatile |
public readonly int Read() | 値型の readonly メンバ |
Add(1) / Add(1, 2) | 引数の数による選択 |
Show(1) / Show("a") | 引数の型による選択 |
Show(int) が Show(long) に勝つ | 変換の少ない候補の優先 |
Sum(1, 2) | 可変長引数への展開 |
Sum(int,int) が params に勝つ | 通常の候補の優先 |
Add(1) | 既定の引数の省略 |
Pick(1, 2) | 引数からの推論 |
First(new int[] { 1 }) | 配列の要素からの推論 |
Left(1, "a") | 2 つの型引数の推論 |
Depth(new int[1][]) | 入れ子の配列からの推論 |
true ? 1 : 2L | ?: の両側からの共通の型 |
public struct Inner { ... } | 入れ子の型 |
public partial class C | 分割して書く型 |
abstract int Get(); / override | 抽象メソッドの実装 |
virtual int Get() / override | 既定の実装の上書き |
書けない形(9)
Section titled “書けない形(9)”| 書き方 | 説明 | エラー | 理由 | 代わりに |
|---|---|---|---|---|
public class Base : TsukimiBehaviour ... public class Leaf : Base | 具象の型を継承する | TUKI0109 | 未定 | 基底を abstract にする |
Fired?.Invoke() | event で通知する | TUKI0108 | 環境 | メソッドを直接呼ぶか、名前を指定して送る |
Fired += Handler | event を購読する | TUKI0108, TUKI0099 | 環境 | 同上 |
public static extern int Native() | 外部の実装を宣言する | TUKI0001 | 環境 | 実行環境のメソッドを呼ぶ |
Read(int v) と Read(in int v) を並べる | 渡し方の違いで候補を分ける | TUKI0001 | 未定 | 名前を変える。in 単独は使える(変数と引数の渡し方) |
public int Twice { get { … } set { … } }(struct の中) | 書き換えられる計算プロパティ(値型) | TUKI0001 | 未実装 | get だけにするか、メソッドにする(struct と record) |
public int Extra { get; set; }(record の中) | プロパティ(record) | TUKI0001 | 設計 | 位置パラメータにするか、メソッドにする |
c[0] = 1;(struct の中の添字) | 添字への書き込み(値型) | TUKI0001 | 未実装 | 新しい値を返すメソッドにするか、ふるまい側の添字を使う |
panel[0](別のふるまいの添字) | 別のふるまいの添字を読む | TUKI0001 | 未定 | 相手側にメソッドを置いて、それを呼ぶ |
event は宣言だけがコンパイルを通ります。Fired += Handler と書いた行と、Fired?.Invoke() と書いた行で TUKI0108 が出ます。 |
~C() と volatile は、コンパイルも実行も通ります。エラーも警告も出ませんが、書いても動きは変わりません。型そのものを初期化するメンバ(静的コンストラクタ・モジュール初期化子)も走りません(初期化と実行順序)。
プロパティが通るかどうかは、置く先とアクセサの形で変わります。
| 置く先 | 自動プロパティ | 計算する(get だけ) | 計算する(set あり) |
|---|---|---|---|
| Behaviour | 書ける | 書ける | 書ける |
struct | 書ける | 書ける | 書けない |
record | 書けない | 書けない | 書けない |
| インタフェース | 書ける(実装する側も自動プロパティにする) | 書けない | — |
using UnityEngine;using Tsukimi;
public class MemField : TsukimiBehaviour{ private int count;
void Start() { Debug.Log(count); // => 0 }}宣言と同時の代入
Section titled “宣言と同時の代入”using UnityEngine;using Tsukimi;
public class MemFieldInitializer : TsukimiBehaviour{ private int count = 5;
void Start() { Debug.Log(count); // => 5 }}using UnityEngine;using Tsukimi;
public class MemConst : TsukimiBehaviour{ private const int Max = 10;
void Start() { Debug.Log(Max); // => 10 }}静的フィールド
Section titled “静的フィールド”インスタンスを作らずに読み書きします。値はふるまいの実体ごとに別で、実体のあいだで共有されません。
using UnityEngine;using Tsukimi;
public class MemStaticField : TsukimiBehaviour{ private static int Count;
void Start() { Count = 1; Debug.Log(Count); // => 1 }}静的な読み取り専用フィールド
Section titled “静的な読み取り専用フィールド”static readonly は書けますが、型が struct のものは通りません(struct と record)。
using UnityEngine;using Tsukimi;
public class MemStaticReadonly : TsukimiBehaviour{ private static readonly int Max = 10;
void Start() { Debug.Log(Max); // => 10 }}メソッドの宣言
Section titled “メソッドの宣言”using UnityEngine;using Tsukimi;
public class MemMethod : TsukimiBehaviour{ private void Do() { Debug.Log(1); } // => 1
void Start() { Do(); }}戻り値のあるメソッド
Section titled “戻り値のあるメソッド”using UnityEngine;using Tsukimi;
public class MemMethodReturn : TsukimiBehaviour{ private int Get() { return 1; }
void Start() { Debug.Log(Get()); // => 1 }}引数のあるメソッド
Section titled “引数のあるメソッド”using UnityEngine;using Tsukimi;
public class MemMethodParameters : TsukimiBehaviour{ private int Add(int a, int b) { return a + b; }
void Start() { Debug.Log(Add(1, 2)); // => 3 }}using UnityEngine;using Tsukimi;
public class MemDefaultArgument : TsukimiBehaviour{ private int Add(int a, int b = 2) { return a + b; }
void Start() { Debug.Log(Add(1)); // => 3 }}名前つき引数
Section titled “名前つき引数”using UnityEngine;using Tsukimi;
public class MemNamedArgument : TsukimiBehaviour{ private int Add(int a, int b) { return a + b; }
void Start() { Debug.Log(Add(b: 2, a: 1)); // => 3 }}オーバーロード
Section titled “オーバーロード”using UnityEngine;using Tsukimi;
public class MemOverload : TsukimiBehaviour{ private int Add(int a, int b) { return a + b; }
private float Add(float a, float b) { return a + b; }
void Start() { Debug.Log(Add(1, 2) + Add(1f, 2f)); // => 6 }}式形式のメソッド
Section titled “式形式のメソッド”using UnityEngine;using Tsukimi;
public class MemExpressionBodied : TsukimiBehaviour{ private int Twice(int n) => n * 2;
void Start() { Debug.Log(Twice(2)); // => 4 }}静的メソッド
Section titled “静的メソッド”using UnityEngine;using Tsukimi;
public class MemStaticMethod : TsukimiBehaviour{ private static int Zero() { return 0; }
void Start() { Debug.Log(Zero()); // => 0 }}自動プロパティ
Section titled “自動プロパティ”using UnityEngine;using Tsukimi;
public class MemAutoProperty : TsukimiBehaviour{ public int Value { get; set; }
void Start() { Value = 1; Debug.Log(Value); // => 1 }}計算するプロパティ
Section titled “計算するプロパティ”get の本体を自分で書くプロパティです。struct の中では set を書けません(struct と record)。
using UnityEngine;using Tsukimi;
public class MemComputedProperty : TsukimiBehaviour{ private int n;
public int Doubled { get { return n * 2; } }
void Start() { n = 3; Debug.Log(Doubled); // => 6 }}取得と設定で異なる可視性
Section titled “取得と設定で異なる可視性”using UnityEngine;using Tsukimi;
public class MbAccessorAcc : TsukimiBehaviour{ void Start() { V = 1; Debug.Log(V); // => 1 }
public int V { get; private set; }}プロパティの初期値
Section titled “プロパティの初期値”using UnityEngine;using Tsukimi;
public class MbAutoPropInit : TsukimiBehaviour{ void Start() { Debug.Log(V); // => 1 }
public int V { get; set; } = 1;}取得だけの自動プロパティ
Section titled “取得だけの自動プロパティ”using UnityEngine;using Tsukimi;
public class MbGetterOnly : TsukimiBehaviour{ void Start() { Debug.Log(V); // => 0 }
public int V { get; }}init アクセサ
Section titled “init アクセサ”using UnityEngine;using Tsukimi;
public class MbInitAccessor : TsukimiBehaviour{ void Start() { Debug.Log(V); // => 0 }
public int V { get; init; }}裏のフィールドへの属性
Section titled “裏のフィールドへの属性”using UnityEngine;using Tsukimi;
public class MbFieldAttr : TsukimiBehaviour{ void Start() { Debug.Log(V); // => 0 }
[field: SerializeField] public int V { get; set; }}仮想プロパティ
Section titled “仮想プロパティ”virtual を付けたプロパティです。派生した型で上書きするには、基底の型を abstract にします。
using UnityEngine;using Tsukimi;
public class MbVirtualProp : TsukimiBehaviour{ void Start() { Debug.Log(V); // => 1 }
public virtual int V { get { return 1; } }}this[int i] を宣言すると、その型の値を v[i] の形で読めます。角括弧に書いた値は、アクセサの引数として届きます。
using UnityEngine;using Tsukimi;
public class MbIndexer : TsukimiBehaviour{ void Start() { Debug.Log(this[2]); // => 20 }
public int this[int i] { get { return i * 10; } }}添字への書き込み
Section titled “添字への書き込み”set も書くと v[i] = x の形で書き込めます。value に書き込む値が入り、添字は引数で受け取ります。
using UnityEngine;using Tsukimi;
public class MbIndexerSet : TsukimiBehaviour{ private int a; private int b;
void Start() { this[0] = 3; this[1] = 4; Debug.Log(this[0] * 10 + this[1]); // => 34 }
public int this[int i] { get { return i == 0 ? a : b; } set { if (i == 0) { a = value; } else { b = value; } } }}宣言だけできる形
Section titled “宣言だけできる形”event の宣言
Section titled “event の宣言”event の宣言はコンパイルを通ります。購読と発火の行を書くと TUKI0108 が出ます。
using UnityEngine;using Tsukimi;
public class MbEventField : TsukimiBehaviour{ void Start() { Debug.Log(1); // => 1 }
public event System.Action Fired;}購読の受け口の記述
Section titled “購読の受け口の記述”add と remove を自分で書く形も、宣言だけは通ります。
using UnityEngine;using Tsukimi;
public class MbEventAcc : TsukimiBehaviour{ void Start() { Debug.Log(1); // => 1 }
public event System.Action Fired { add { } remove { } }}書けるが何も起きない形
Section titled “書けるが何も起きない形”ファイナライザ
Section titled “ファイナライザ”ファイナライザを呼ぶ仕組みが実行環境に無いので、本体は一度も走りません。
using UnityEngine;using Tsukimi;
public class MbFinalizer : TsukimiBehaviour{ void Start() { Debug.Log(1); // => 1 }
~MbFinalizer() { }}volatile
Section titled “volatile”同時に動く実行の流れが無いので、volatile を付けても読み書きの意味は変わりません。
using UnityEngine;using Tsukimi;
public class MbVolatile : TsukimiBehaviour{ void Start() { Debug.Log(V); // => 0 }
private volatile int V;}値型の readonly メンバ
Section titled “値型の readonly メンバ”値を書き換えないメンバに付けられます。値型は渡すたびに複製されるので、付けても実行時のふるまいは変わりません。
using UnityEngine;using Tsukimi;
public struct Point { public int X; public readonly int Read() { return X; } }public class MbReadonlyMember : TsukimiBehaviour{ void Start() { Point p = new Point(); Debug.Log(p.Read()); // => 0 }}候補の選ばれ方
Section titled “候補の選ばれ方”引数の数による選択
Section titled “引数の数による選択”using UnityEngine;using Tsukimi;
public class OvByArity : TsukimiBehaviour{ void Start() { Debug.Log(Add(1)); // => 1 Debug.Log(Add(1, 2)); // => 3 }
private int Add(int a) { return a; } private int Add(int a, int b) { return a + b; }}引数の型による選択
Section titled “引数の型による選択”using UnityEngine;using Tsukimi;
public class OvByType : TsukimiBehaviour{ void Start() { Debug.Log(Show(1)); // => 1 Debug.Log(Show("a")); // => 2 }
private int Show(int a) { return 1; } private int Show(string a) { return 2; }}変換の少ない候補の優先
Section titled “変換の少ない候補の優先”using UnityEngine;using Tsukimi;
public class OvBetterConv : TsukimiBehaviour{ void Start() { Debug.Log(Show(1)); // => 2 }
private int Show(long a) { return 1; } private int Show(int a) { return 2; }}可変長引数への展開
Section titled “可変長引数への展開”using UnityEngine;using Tsukimi;
public class OvExpanded : TsukimiBehaviour{ void Start() { Debug.Log(Sum(1, 2)); // => 2 Debug.Log(Sum(new int[] { 1, 2 })); // => 2 }
private int Sum(params int[] xs) { return xs.Length; }}通常の候補の優先
Section titled “通常の候補の優先”using UnityEngine;using Tsukimi;
public class OvNormalBeatsParams : TsukimiBehaviour{ void Start() { Debug.Log(Sum(1, 2)); // => 1 }
private int Sum(int a, int b) { return 1; } private int Sum(params int[] xs) { return 2; }}既定の引数の省略
Section titled “既定の引数の省略”using UnityEngine;using Tsukimi;
public class OvDefaultArg : TsukimiBehaviour{ void Start() { Debug.Log(Add(1)); // => 3 Debug.Log(Add(1, 5)); // => 6 }
private int Add(int a, int b = 2) { return a + b; }}型引数の推論
Section titled “型引数の推論”引数からの推論
Section titled “引数からの推論”using UnityEngine;using Tsukimi;
public class OvInferArgs : TsukimiBehaviour{ void Start() { Debug.Log(Pick(1, 2)); // => 1 }
private T Pick<T>(T a, T b) { return a; }}配列の要素からの推論
Section titled “配列の要素からの推論”using UnityEngine;using Tsukimi;
public class OvInferLower : TsukimiBehaviour{ void Start() { Debug.Log(First(new int[] { 1 })); // => 1 }
private T First<T>(T[] xs) { return xs[0]; }}2 つの型引数の推論
Section titled “2 つの型引数の推論”using UnityEngine;using Tsukimi;
public class OvInferTwo : TsukimiBehaviour{ void Start() { Debug.Log(Left(1, "a")); // => 1 }
private T1 Left<T1, T2>(T1 a, T2 b) { return a; }}入れ子の配列からの推論
Section titled “入れ子の配列からの推論”T[][] のような入れ子の配列からも、要素の型が決まります。
using UnityEngine;using Tsukimi;
public class OvInferNested : TsukimiBehaviour{ void Start() { Debug.Log(Depth(new int[1][])); // => 1 }
private int Depth<T>(T[][] xs) { return xs.Length; }}?: の両側からの共通の型
Section titled “?: の両側からの共通の型”using UnityEngine;using Tsukimi;
public class OvBestCommon : TsukimiBehaviour{ void Start() { long v = true ? 1 : 2L; Debug.Log(v); // => 1 }}継承と入れ子
Section titled “継承と入れ子”using UnityEngine;using Tsukimi;
public class MemNestedType : TsukimiBehaviour{ public struct Inner { public int V; }
void Start() { Inner i = new Inner(); Debug.Log(i.V); // => 0 }}分割して書く型
Section titled “分割して書く型”using UnityEngine;using Tsukimi;
public partial class R_part : TsukimiBehaviour{ void Start() { Debug.Log(Helper()); }}
public partial class R_part{ private int extra;
int Helper() { extra = 41; return extra + 1; }}抽象メソッドの実装
Section titled “抽象メソッドの実装”using UnityEngine;using Tsukimi;
public abstract class MemAbstractBase : TsukimiBehaviour{ public abstract int Get();}
public class MemAbstractLeaf : MemAbstractBase{ public override int Get() { return 1; }
void Start() { Debug.Log(Get()); // => 1 }}既定の実装の上書き
Section titled “既定の実装の上書き”virtual のメソッドを override で上書きできます。基底の型は abstract である必要があります。
using UnityEngine;using Tsukimi;
public abstract class MemVirtualBase : TsukimiBehaviour{ public virtual int Get() { return 0; }}
public class MemVirtualLeaf : MemVirtualBase{ public override int Get() { return 1; }
void Start() { Debug.Log(Get()); // => 1 }}