11. 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() がコンストラクターを呼ぶようにするには
ここも仕様変更に
20. 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. 背景
• declaration expressions自体は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句にスコープが漏れると
むしろ使いにくい
26. 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() { … }
}