C# 7に向けて(3): その他
1/21, 28のDesign Notes付近の、C# チーム公式の「C# 7 提案」紹介3個目。
(以前の2つにもリンク)
さて、あと大きめの話題というと、method contracts と pattern matching が残ってはいるんですが。2回連続で結構長めのブログ書いたので、今日は先に「その他」的なものを3つ。
- Proposal: [DoesNotReturn] #127
- Proposal: Static Linking #162
- Proposal: Add completeness checking to pattern matching draft specification #188
[DoesNotReturn]
1つ目は割かしほんとにその他枠。
C#の場合、戻り値を持つ(voidでない)メソッドは、ちゃんとどの分岐でも値を返しているか(もしくは、例外を投げて終わっているか)をチェックしています(返していないところがあったらコンパイル エラー)。
しかし、現状だと判定できないものが1つあって、元から例外を投げる意図で別のメソッドを呼び出す場合。100%常に例外を投げるメソッドを呼んだ場合、その後ろのステートメントは絶対に実行されないはずですが、これを判定するすべがない。
なので、こういう「戻ってこない」「絶対例外投げて終わる」メソッドを示す用の属性を追加したいという提案。
まあ、もう少し例外ハンドリングの仕組み自体に改善の余地はないの?とは思うものの、「低コストでたまに便利」的な意味ではよさそう。
Static Linking
2つ目。テーマ的には Componentization の一部。
今、.NETのライブラリは基本的には動的リンクしかなくて、大半のケースではそれで特に問題もないんですが。特定の用途に置いては明らかに静的リンクが有利な場合があります。
提案内で例に上がっているのは、小さな機能が山ほど詰まったヘルパー ライブラリです。具体例でいうと、LINQみたいなやつでしょうね、小さい静的メソッドが大量に詰まってるやつ。1つのプログラムでその全機能を使うことはほぼなくて、使わない部分をクライアントにダウンロードさせるのはもったいない。使うところだけをプログラム中に埋め込みたい。
正しく使えば性能面で有利なのはわかるんですが… ちゃんと有利なものに使われるかとか、むしろ使っちゃいけない場面で使われないか(セキュリティ ホールとかの申告な問題が見つかった時にどうするの?とか)考えて使われるかなぁ…という心配が。
Completeness
3つ目。pattern matching 関連なので、ほんとは pattern matching の話の後の方がいい気もするものの。pattern matching の提案とは別に、後から追加された提案です。
pattern matching、要するに、型を見て分岐する際に、「意図したすべての型を網羅している」というのをチェックしたいことがあります。↓こういうの。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Message { } | |
class A : Message { } | |
class B : Message { } | |
class C : Message { } | |
class PatternMatching | |
{ | |
public static void Match(Message m) | |
{ | |
if (m is A) { /* … */ return; } | |
if (m is B) { /* … */ return; } | |
if (m is C) { /* … */ return; } | |
// もう所望の全パターン網羅済み! | |
// ここに来るはずがない! | |
// というか、ここに来ない保証がほしい。 | |
} | |
} |
こういうのをチェックできる状態を、完全(complete)と呼びたいみたいです。
数学用語使って「完備」(代数学におけるcompleteの訳語)とか言った方がいいかも。(一定のルール下で)これ以上集合的に拡大できない状態。これ以上元が増えない保証。
型階層が完備であることを保証するためには、要するに、第三者が子クラスを足せないことを保証してやる必要があります。現状のC#でもこれを保証する方法があって、以下のようなパターンで実装すればOK。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
abstract class Message | |
{ | |
// コンストラクターを private に | |
private Message() { } | |
// inner クラスであれば private なコンストラクターにアクセスできる | |
// なので、以下の A, B, C はコンパイルできる | |
public sealed class A : Message { } | |
public sealed class B : Message { } | |
public sealed class C : Message { } | |
} | |
// private なコンストラクターのせいで外からは継承できない | |
public class D : Message { } // なので、ここでコンパイル エラー | |
// しかも、A, B, C ともに sealed なので、そいつらを継承することもできない |
このパターンをもって「完備である」とするか、もしくは、こういうコードを生成するようなシンタックス シュガー(今のところ abstract sealed っていう修飾子で提案)を追加したいとのこと。
[…] その3で説明した「completeness」 […]
C# 7に向けて(6): Pattern matching | ++C++; // 未確認飛行 C ブログ
2015年2月7日 at 03:20
[…] C# 7に向けて(3): その他 […]
Roslyn issues 2015/2/16 | ++C++; // 未確認飛行 C ブログ
2015年2月16日 at 02:20
[…] 完備性のチェック(2/3のブログのcompletenessのところ参照)はした方がいい? […]
ピックアップ Roslyn 3/29 | ++C++; // 未確認飛行 C ブログ
2015年3月29日 at 22:57