前回ラムダ形式プロパティを紹介しました。ラムダ式チックなメンバー (Expression-bodied members) は、Visual Studio 14 CTP 2まではプロパティしか実装されていませんでしたが、一昨日 (2014/08/19) リリースされたVisual Studio 14 CTP 3にはメソッド版も搭載されました。
ラムダ形式メソッド
ラムダ形式メソッドは次のように記述します。引数が付いただけで、ラムダ形式プロパティとほとんど変わりません。
public class Point { public uint X { get; }; public uint Y { get; }; public double CalculateDistance(Point point) => Sqrt(Pow(X - point.X, 2) + Pow(Y - point.Y, 2)); public Point(uint x, uint y) { this.X = x; this.Y = y; } }
たったこれだけでメソッドを記述することができます。上記は戻り値を返すタイプですが、もちろん以下のように戻り値をvoidにするも可能です。
class Person { public string Name { get; }; public void SayHello() => WriteLine("I'm {0}.", Name); public Person(string name) { this.Name = name; } }
これによりメソッドの記述が非常に簡潔になりました。しかし、残念ながら複数のステートメントを持つ形式のラムダ式はサポートされていません。メソッドが1行で完結しない場合は、これまで通りのメソッドを作る必要があります。
public class Point { public uint X { get; }; public uint Y { get; }; public double CalculateDistance(Point point) => //--- コンパイルエラー { var dx2 = Pow(X - point.X, 2); var dy2 = Pow(Y - point.Y, 2); return Sqrt(dx2 + dy2); } public Point(uint x, uint y) { this.X = x; this.Y = y; } }
逆コンパイル
もはやほぼお約束ですが、ラムダ形式メソッドが既存コードとしてどのように展開されるのかを逆コンパイルで見てみます。
class Point { public uint X { [CompilerGenerated] get { return this.<X>k__BackingField; } } public uint Y { [CompilerGenerated] get { return this.<Y>k__BackingField; } } public Point(uint x, uint y) { this.<X>k__BackingField = x; this.<Y>k__BackingField = y; base..ctor(); } public double CalculateDistance(Point point) { return Math.Sqrt(Math.Pow(this.X - point.X, 2.0) + Math.Pow(this.Y - point.Y, 2.0)); } }
完全にお察しの通りだと思いますが、ごく普通のメソッドに展開されます。展開された内容を見ると、C# 6.0ベースのコードは、すごくコード量が減ることが分かりますね。