ブログ: What’s New in C# 7.0

Roslynリポジトリ内の話じゃないんですけど、Preview 4でのC# 7の動きについて、Madsがブログ書いてました。

7.0

そういや、この文章だと「C# 7.0」。 昔ちょっとブログ書きましたけど、最近って小数点以下のバージョン付けないんですけど。 C# 7はずっと「7」ばっかりみてたけど、久々に「7.0」表記。 この辺り、最近、C#チーム内でも統一してないなぁ…

C# 7.0の内容

このブログの内容的には、 先日僕もブログで書いたのとそんなに差がないんで詳細は省略。

差分というか、僕が書いた方で漏れてるのは、以下の内容:

out varのwildcard

out varと一緒に、*、要するに、受け取る必要のない out 引数を無視するための「wildcard」も入れるかもという話もあるみたい。

*は、 元々、パターン マッチング構文の1機能(パターンの1種)です。 で、out varもパターン マッチングと同列で検討されてた機能です。

今、C# 7で、out varだけは先に入れる方向で実装が進んでいるわけですが、どこまで一緒に前倒すかという問題。 out varに対する*はC# 7で入れるかどうかまだ迷ってるっぽいです(C# 7時点で入らないとしても、たぶんパターン マッチングとは同時に入る)。

More expression bodied members

今、メソッドとget-onlyなプロパティに限り、式が1つだけの実装に => を使えるわけですが。 それを、コンストラクター、デストラクター、getとset両方あるプロパティに対しても使えるようにするやつ、C# 7で入りそうらしい。

この機能、完全にコミュニティ主体の実装なんですよね。 3月にブログ書いてますけど、この機能はずっと「需要がある程度あるのはわかるけど、メリット小さめだし後回しになってる」みたいな状態でおいておかれてたものなんですけど、それに対して、「実装したよ」ってプルリクエスト送ってきた人がいて。 C#チームが「そのプルリクを取り込むことにした」って書き込みはしてたんですが、その後音沙汰なしでした。 久々に見たと思ったら、C# 7のタイミングで取り込むことにしたんですねぇ。

Throw expressions

これ、結局どうなるんだろ…

Language Feature Status」からは、むしろ、つい最近「7じゃなくて7の次で」降格したところなんですけど。 どっちが正しいんだか…

MSDNブログ

そういや、気が付いたら、MSDNブログから「C#チーム ブログ」「VBチーム ブログ」は消えてるんですよね。 Roslynのgithubリポジトリに一本化して、もうブログは書かないのかと思ってたら。

.NET配下でブログ書きますか。

コメント欄

で、なんだかんだ言って、ブログはコメントたくさんつきますね…

いくつか、気になったの拾っておきます。

contract

「design by contract」については何もないの?とのコメントが。

返信ついてて、「今のタイミングでは何もしない。contractはいまいち煩雑で複雑になりがちだし、そんなに大々的な検討もしてない。contractの用途的に、9割がたはnullチェックに関するものだけど、それは型システム指向で『非null参照型』を次のメジャー リリース向けに検討してる。」

VB

VBは?沈みゆく船だからC#に移った方がいい?

に対して、他の人から「頼む、ほんとお願いだからVBの質問しないで。死なせてあげて」とかついてる。

さらにそれに対して、VBのPMの人が「頼む、ほんとお願いだからVBの質問し続けて。フィードバックもらえることがほんとものすごい重要だから」とか返信してるという。

どこの国でも似たような状態ですよねぇ。 VBが死ぬときは、今のVBユーザーが絶滅したときであって、VB使ってない外野がとやかく言うなよっていつも思うんですが。

wildcard? *なの?nullとかでいいんじゃない?

*とかきもくない?↓みたいな、null使う文法の方がよくない?とか言ってる人が。

p.GetCoordinates(out int x, null); // Ignore return
p.GetCoordinates(out int x, out null); // Alternative ignore return

何この、見た印象ぬるぽ起こしそうな構文… 値を受け取るべき場所にnull書くとかちょっと…

そして飛び火して、本題からそれて「nullはこの世から消えるべき」主張をこのコメント内でし始める人まで現れる始末。

タプルとout var両方やるの?

タプルもout varも、多値戻り値を返すために使う(ことが多い)構文なわけですが、 なので当然「どっち使えばいいの?なんで両方やってるの?」という質問も。

それに対する答え:

  • だいたいの場合においてはタプルを使うといいよ
  • ただし、以下の場合においてout引数が残る余地がある
    • 複数のオーバーロードを用意したい場合(タプルというか、戻り値だとオーバーロードできない)
    • Tryパターンなんかだと、単一のboolを返す意味がある。ifステートメントの条件式とかで使えるように

ちなみに、別のコメントに対する返答で、今このタイミングでout引数に対する拡張を入れる意味について「パターン マッチングとout varには相乗効果がある」との回答あり(要するに、パターン マッチングのついで。パターン マッチングをやるならこちらも)。

C#がどんどん汚染されてない?

だいたいの人は「便利!待ち遠しい!」って言ってる中、まあ、毎度必ずいるわけですが「ちょっとトリッキーすぎない?泥沼にはまりそうで嫌だわ」って言い出す人が。 C# 7に限らずこれまでも、C#に限らずありとあらゆる言語でこういう意見絶対出てくるわけですが。

それに対する Mads の回答:

あなたは言語の進化のある種の核心をついてる。我々は機能を足せるけど、絶対に消せない。C#の進化においてもこのことが重くのしかかってる。 Anders (元祖、C#/.NETの父)の発言は有名だけど、「あらゆる機能はマイナス100ポイントから始めろ」と言ってる。 全ての機能について、我々は誰が喜ぶか、今現在だけでなく、今から10年後のことも考えるようにしている。 今現在有用かどうかだけでなく、永久に言語の一部分を占め続けるということを考えるようにしている。

我々はだいたいは正しいが、常に正しいわけではない。わかるだろうが、未来というのは予測が最も難しいものの1つだ。 このことは、言語設計のアプローチに対する異なる側面をもたらす。 我々は大胆でなければならない。 我々は遠い未来への責任に追い詰められてはいけない。 なぜなら、さもなくばその未来も得られないから。 C#は今この時「最高のプログラミング言語」の1つでなければならない。 さもなくば、明日にはそうではなくなってしまう。

なので、我々は少々アグレッシブに機能を追加する。 開発者にとって最も価値ある機能を追加しようと試みる。 さらに、その機能を追加するにあたって、言語の複雑性が増すという観点から不利益が最小になるよう試みる。 たとえばそう、パターン マッチングは新しい機能になるわけだが、しかし、既存の言語要素、例えばisswitch、既存の型の中で動くものだ。 それは(うまくいけば)我々の過去とよく統合されている。 同時に、いくつかのパターンを、将来の発展の余地を残しつつ、今現在の「税負担」にならないように導入している。 それは、我々のもっともらしくあり得そうな未来とよく統合されている。

信じられないかもしれないが、我々が何パターンかあり得そうな未来について、取り組む余地を確実に残せるよう、投機的な設計にどれだけ時間をついやしていることか。 これは、我々が、新機能を追加するにあたって、この言語を長期的にわたって健康で生存力がある状態に保てるよう試みていることの一部分だ。

以上で、我々がC#の長期的な進化についてどのくらい考えているか、その姿を伝える助けになれば幸いだ。