なんでも拡張
拡張メソッドは便利な構文なわけですが、インスタンス メソッドしか拡張できないのが残念なところです。拡張プロパティとかも作りたいことがあるし、静的な拡張(静的メソッドも既存のクラスに対して追加したように見える構文)もほしかったりします。という、なんでも拡張できる構文の案。
今のところ、以下のような構文で検討中。
extension class クラス名 : 拡張したい型
{
// ここにメンバーは、拡張したい型の拡張メソッド、拡張プロパティなどになる
}
C# Design Notes (タプル型関連 再び)
前回のC# Design Notes for Apr 12-22, 2016に引き続き、タプル型関連。
-
分解
(x, y) = tuple;
みたいなのを、tuple.Deconstruct(out x, out y);
みたいなメソッド呼び出しとして解釈したい- タプル型専用の特別な構文にしないために、インスタンス or 拡張メソッドを通したい
- ちょっと前まで
GetValue
って名前を検討してたけど、一般的過ぎてすでに使われてそうなので、Deconstruct
メソッドにする - 要素の値を返すのはout引数にする。タプル型を分解するのにタプル型を返すわけにもいかないので
-
switchステートメントでの変換
- 既存のswitchだとintとかstringしか受け付けないので、intとかへの暗黙的型変換できる型は変換結果で解釈されてた
- 破壊的変更にならないようにするために、暗黙的型変換を定義した型は、今後も変換結果で解釈する
- なので、そういう型(例えばintへの暗黙的型変換を持った
Const
型)はcase Const(int i):
みたいなcaseにマッチしない(case 0:
とかにはマッチする) - あんまり起きない状況だし、破壊的変更を避ける方を優先
-
タプル型間の変換
- 「要素数が一致していて、各要素が暗黙的型変換できるなら、タプル型間でも暗黙的型変換できる」ってルールにするっぽい
-
タプル風のインスタンス生成
- 任意の型に対して、左辺から型が推論できるなら、
new (x, y)
みたいな書き方でインスタンス生成できるようにする
- 任意の型に対して、左辺から型が推論できるなら、
最後の「タプル風インスタンス生成」はちょっと補足。
元々の発想は、「分解の構文をDeconstruct
メソッドを通すことで汎用化したんだし、構築の構文も汎用化すべき」というもの。タプル構築と、コンストラクター呼び出しを紐づけたいということになります。
が、例えば、その発想で行くと、以下のように、なんか直観にそぐわない「タプル型リテラルからの構築」ができてしまう。
Dictionary<int, string> d = (16, EqualityComparer<int>.Default); // さすがにこれは気持ち悪い
代わりと言ってはなんだけど、以下のような、new
の後ろの型の省略を認めようという感じになってるみたい。
Point p = new (3, 4); // new Point(3, 4) と同じ
List<string> l1 = new (10); // 引数0個 or 1個でも大丈夫
List<int> l2 = new () { 3, 4, 5 }; // コレクション初期化子との併用もできるけど、() は省略できない
要するに、結局、左辺からの型推論みたいな構文を追加することになりそう。