Parameterless Constructors •Design Notes 8/27† • The meeting focused on rounding out the feature set around structs. 1. Allowing parameterless constructors in structs <allow, but some unresolved details> 2. Definite assignment for imported structs <revert to Dev12 behavior> † https://roslyn.codeplex.com/discussions/562559
12.
背景: 既定値 •値型の既定値は0クリア var points = new Point[1000]; • Pointが構造体のとき、コンストラクターを1000回呼ぶのか • 呼びたくないので、memset(0)にしたい
13.
背景: new T()• 現状、new T()で既定値を作る var p = new Point(); 0クリア • 構造体はパラメーターなしのコンストラクターを持 てない
14.
背景: default(T) •.NET 2.0以降には、既定値用のdefault(T)がある var p = default(Point); 0クリア var p = new Point(); これで0クリアする必要まだある? • ちなみに コンストラクター呼んでもよくない? • .NET IL仕様上は構造体がパラメーターなしのコンス トラクター持てる • C#のコンパイラーレベルでエラーにしてる
15.
問題: genericsのnew T()制約• new T() == default(T) 前提の最適化 T M<T>() where T : new() { return new T(); } Tが構造体の時、0クリアに 最適化してしまう • new T() がコンストラクターを呼ぶようにするには ここも仕様変更に
Declaration Expressions •Design Notes 9/3† • The meeting focused on rounding out the design of declaration expressions 1. Removing “spill out” from declaration expressions in simple statements <yes, remove> 2. Same name declared in subsequent else-if’s <condition decls out of scope in else-branch> 3. Add semicolon expressions <not in this version> 4. Make variables in declaration expressions readonly <no> † http://roslyn.codeplex.com/discussions/565640
21.
背景 • declarationexpressions自体はCTP 2で入ってる • 式の途中で変数宣言 var n = int.TryParse(s, out var x) ? x : 0; if ((var x = obj as C) != null) { } else { } var y = (var x = GetValue()) * x; p.GetCoordinates(out var x, out var y); • 問題は、この変数xのスコープがどこまで続くか
22.
検討: 宣言した変数のスコープ •現仕様 • 宣言後、ブロックの終わりまで { var p = new Point(); p.GetCoordinates(out var x, out var y); var p = x * y; // OK Console.WriteLine("{0} = {1} × {2}", p, x, y); } // ここから先、x, y 使えない • 検討事項 • ステートメント内に限るべきではないか • if-elseの場合、else句ではどうするか
23.
検討: ステートメント内に限る •ほんとうにステートメントの外で使う? ステートメント内 var n = int.TryParse(s, out var x) ? x : 0; var y = (var x = GetValue()) * x; p.GetCoordinates(out var x, out var y); var p = x * y; Console.WriteLine("{0} = {1} × {2}", p, x, y); xを使いたい範囲 ステートメント内 こいつ、要る? • C#だと、多値戻り値自体あまり推奨されてない • = 利用場面少ない • =レアケースのためにxのスコープ広げる? • ステートメント内に限った方がよくない?
24.
検討: if-else •else句で使いたい? • →使いたい方がレアケース else句で意味ある値持ってない if (int.TryParse(s, out var x)) { } if ((var x = obj as A) != null) { } else if ((var x = obj as B) != null) { } else { } else句にスコープが漏れると むしろ使いにくい
Pattern Matching •Draft spec for records and pattern-matching in C#† • C#にも型のパターンマッチングが入りそう • 現在はdraft • 実装もあり(まだmasterブランチには入ってない) † http://roslyn.codeplex.com/discussions/560339
27.
パターンマッチング式 • isを拡張if (exp is Add(Expression left, Expression right) { … } • switchも拡張 switch (exp) { case Add(Const(0), var x): return x; case Mul(Const(0), var x): return Const(0); }
28.
operator is •型判定+is演算子に展開 static bool operator is(Cartesian c, out double x, out double y) { x = c.X; y = c.Y; return true; }
29.
record型 • is,Equals, GetHashCode, ToStringの自動生成 • プライマリコンストラクターの引数から プロパティを自動生成 record class Point(int X, int Y) { } class Point(int x, int y) { public int X { get; } = x; public int Y { get; } = y; public static bool operator is(…) { … } override public bool Equals(object obj) { … } override public int GetHashCode() { … } override public string ToString() { … } }