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() { … }
}