.NET Compiler Platform (Roslyn) Preview
Roslynが1年以上ぶりに公開されました。
オープンソース化
おまけにオープンソース化(ライセンスは Apache License 2.0)のニュース付き。
ソースコードはページ内からのダウンロードもできるし、git cloneも可能
- git clone https://git01.codeplex.com/roslyn
Roslynの成果物
- End-User Preview
- Visual Studio上で、C#プロジェクトで使ってるコンパイラーとかリファクタリング機能がRoslyn版にさし変わる
- 後述するC# 6.0新機能(のうちのいくつか)も使えるようになる
- Roslyn SDK Project Template
- Roslynを使ったVisual Studio拡張を作るためのテンプレート集
- Roslyn Syntax Visualizer
- C#のソースコードのカーソルがある位置が、シンタックス ツリーのどこにあたるかを全部見れる
- ↓こんなの
- Microsoft.CodeAnalysisパッケージ
- 自分のプログラムから参照できるRoslynライブラリのNuGetパッケージ
- Install-Package Microsoft.CodeAnalysis
残念ながら、C#スクリプトがらみの、「C#スクリプトのアイテム テンプレート」とか「C# Interactiveウィンドウ」は現状ではないみたい(ロードマップにだけある)。
C#の新機能候補
今日公開されたバージョンのRoslyn(の新C#/VBコンパイラー)は、すでにいくつか、次期バージョンの来るべき機能が実装されてるみたい。
SDKとかと一緒に、「Upcoming Features in C#/VB」っていうドキュメントが入っているので、詳しくはそちらを参照。
ちなみに、「もっと多くの言語機能が計画としてはあるものの、未実装」とのこと(未実装分はドキュメントにはない)。
(去年出てた情報: The Future of C#。確かにいくつかはドキュメントにも実装にもない。)
以下、かいつまんで、というか、コード サンプルをいくつか(実際にRoslyn End-User Previewをインストールするとコンパイルできるコード)。
Primary Constructor
immutableなクラスが作りやすく。
class Point(int x, int y)
{
public int X { get; } = x;
public int Y { get; } = y;
}
要はF#的なコンストラクターの書き方。ちなみにこの書き方だと、パラメーターのxとかyは、初期化にしか使えない。
初期化以外でも使いたい場合には、以下のように、アクセス修飾子を付けて「Field paramters」って状態にする。
class Point(public int X, public int Y)
{
}
(フィールドをpublicにするのはあんまり推奨されないので、これはいい書き方ではないけども。)
Using static
Math. とか Expression. とか省略可能に。
using System.Math;
class Circle(public readonly double Radius)
{
public double GetArea { get { return Radius * Radius * PI; } }
}
Declaration expressions
式の途中で変数宣言可能に。「変数宣言式」(declaration expression)の名前通り、それ自体も式。
static void Main()
{
var num = int.TryParse("123", out var i) ? i : 0;
Get(out var x, out var y);
while ((var s = Console.ReadLine()) != null) Console.WriteLine(s);
}
static void Get(out int x, out int y)
{
x = 10;
y = 20;
}
Exception filters
(ILの仕様的には昔からあったんだけども、C#でも)例外のcatch句に条件付け可能に。
try
{
throw new Exception("b");
}
catch (Exception e) if (e.Message.StartsWith("a"))
{
Console.WriteLine("a");
}
catch (Exception e) if (e.Message.StartsWith("b"))
{
Console.WriteLine("b");
}
Binary literals
ドキュメントに「Try them out in VB」と書かれてる通り、実はC#には実装されてない。以下のように、2進数リテラルを書けるようにする予定。
var bits = 0b0010_1110;
var hex = 0x00_2E;
var dec = 1_234_567_890;
Indexed members and element initializers
オブジェクト初期化子にインデクサーを書けるように。
var data = new Dictionary<string, int>
{
["one"] = 1,
["two"] = 2,
};
これだけだとそんなにうれしくなくて、さらに、stringのキーに対しては以下のような書き方ができるように。
var data = new Dictionary<string, int>
{
$one = 1,
$two = 2,
};
Console.WriteLine(data.$one);
Console.WriteLine(data.$two);
つまるところ、JSON読み込みとかでは、dynamic使わなくても辞書のキー参照に対するシンタックス シュガーで十分じゃない?的な。
Await in catch and finally blocks
catch句、finally句にもawait演算子書けるように。
StreamWriter s = null;
try
{
s = new StreamWriter("data.txt");
await s.WriteAsync("some message");
}
catch (Exception e)
{
using (var errorLog = new StreamWriter("error.txt"))
await errorLog.WriteAsync(e.Message);
}
finally
{
if (s != null)
{
await s.FlushAsync();
s.Close();
}
}
例外catchしたときにログ書き出し(ファイルI/Oは非同期にしたい)とか、Disposeパターンを非同期にしたいとかいうときに困ることがなくなります。
Extension Add methods in collection initializers
コレクション初期化子で呼ばれるAddメソッドが拡張メソッドでもよくなりました。
using System.Collections.Generic;
class Person(string name, string address)
{
public string Name { get; } = name;
public string Address { get; } = address;
}
static class PersonExtensions
{
public static void Add(this IList<Person> list, string name, string address)
{
list.Add(new Person(name, address));
}
//↓のInitializerから、↑の拡張メソッドが呼ばれる
}
class Program
{
static void Main()
{
var list = new List<Person>
{
{ "name 1", "Shinjuku" },
{ "name 2", "Shinagawa" },
{ "name 3", "Chofu" },
};
}
}
[…] で、このデモ中のコードが新機能紹介として優秀な感じだったので、before/after的に並べてみる。具体的にどういう文法なのかはこないだ書いたので今日は割愛。 […]
C# before/after | ++C++; // 未確認飛行 C ブログ
2014年4月6日 at 21:22
[…] 過去の記事: .NET Compiler Platform (Roslyn) Preview […]
.NET vNext | ++C++; // 未確認飛行 C ブログ
2014年5月22日 at 20:00
[…] Features in C#というドキュメントが詳しく、さっそく.NET Compiler Platform (Roslyn) Preview | ++C++; // 未確認飛行 C ブログ: […]
Roslyn build preview公開 - SharpLab.
2015年6月13日 at 09:57