2003年以降で初めて、Microsoftは C# のポイントリリースを検討している。現在 C# 7.1 としてマークされているこの言語の次のバージョンには、非同期 Main、デフォルト式、Tuple Name、そしてジェネリクスによるパターンマッチングが含まれる。
非同期 Main
非同期のコードを実験している開発者をよく苛立たせることとして、現在のコンソールアプリケーションは非同期のエントリーポイントをサポートしていないということがある。回避策は複数行の模範コードを書くことだが、普段は使用されないメソッドに依存しているためこのパターンは理解しづらい。
public static void Main()
{
MainAsync().GetAwaiter().GetResult();
}
private static async Task MainAsync()
{
... // Main body here
}
これに対処するため、非同期 Main の提案では4つの新たなシグネチャーを可能なエントリーポイントのリストに単純に追加する。
static Task Main()
static Task<int> Main()
static Task Main(string[])
static Task<int> Main(string[])
これらのエントリーポイント関数のうち1つが存在していれば、非同期でない Main 関数を使用していたとしても、コンパイラーが必要な模範コードを生成する。この最後の制約は、後方互換のために必要なものだ。
“async void Main()” を実現することが検討されてきたが、それによってコンパイラーがより複雑になるため、一般に Microsoft はイベントハンドラーの外での “async void” の使用には前向きではない。
デフォルト (すなわち Nothing)
C# と VB の間のわずかな違いの 1 つは、 VB は “null” を意味するキーワードを持たない、ということだ。“Nothing” キーワードが存在するが、言語仕様によれば、
Nothing は特別なリテラルです;これは型をもたず、型パラメーターを含む、型システムの全ての型に変換可能です。特定の型に変換されると、その型のデフォルト値に等しい値となります。
現在 C# は “default(T)” パターンを使用して同じ効果を得ているが、特にクラス名が長い場合、少しうんざりする。C# 7.1 を用いると、“default literal” が使用でき、これによって、
この分類の式は任意の型へ、デフォルト値または null で暗黙的にリテラル変換されます。
デフォルトリテラルの型のインターフェイスは null リテラルのものと同様に動作する。ただし許可された型 (参照型だけでなく) に限る。.
デフォルトリテラルは、null を使用していた全ての箇所で使用できる。これは提案にて障害として記述されていたことだが、おそらく同じことをするために 2 つのよく似た方法があることが一般に嫌われるためだろう。設計ミーティングのノートでは以下の問いかけがあった。
私たちはスタイル戦争の準備をしているのですか?
以下がデフォルトリテラルの使用例だ。
ImmutableArray<SomeType> x = default;
return default;
void Method(ImmutableArray<SomeType> arrayOpt = default)
var x = new[] { default, ImmutableArray.Create(y) };
const int x = default;
if (x == default)
if (x is default)
y = default as RefType //compiler warning: always null
int i = default
以下がデフォルトリテラルの不正な使用だ。
const int? y = default;
if (default == default)
if (default is T)
var i = default
throw default
最後は、C# の設計における奇妙なアーティファクトだ。設計ミーティングノートより、
C# において null をスローすることが許可されています。これはランタイムエラーにつながり、皮肉にも NullReferenceException のスローを引き起こします。NullReferenceException をスローすることは卑怯で醜いイディオムです。
これをデフォルトで許可することの正当な理由は存在しません。ユーザーが、そのように動作すべきであると思っている、またはそのように動作していることに意図をもっているとは思えません。
デフォルトリテラルを導入する代わりに、同じ効果を得るために単に “null” を拡張することも検討されている。VC は “nothing” と “null” が異なる文字列であるためにこれが可能だ。VB は null キーワードを使用しなくてもその概念をもち、 “NothingReferenceException” のようなものを目にすることになる。
C# では、“null を使用したとき、それは実際に null であることを意味するのか、あるいは、 null が許可されている、またはいないデフォルト値としての null を意味するのか” ということが恒常的に問われる。結論は、それがあまりに紛らわしいということだ。
Part 2 では、タプルとパターンマッチングを取り上げる。
Rate this Article
- Editor Review
- Chief Editor Action