Visual Studio (Win) で C# 7.2 が使えるらしいので試して見ました。
Visual Studio 2017 15.5 Preview 4 が必要らしいのでインストールします。
今の Visual Studio は同一メジャーバージョン/エディションでも複数インストールできるのではかどりますね。
■ C# 7.2 の設定
プロジェクトを新規に作成したらいつもの手順で、C# 7.2 を使えるように設定します。
プロジェクト > ××のプロパティ > ビルド > (右下の方の)[詳細設定]ボタン > 全般の[言語バージョン] を C# 7.2 に設定
これで、C# 7.2 が使えるはずです。
とりあえず今回は上記のリリースノートに書かれている機能を試してみました。
■ Span を試す
Span を使うには、NuGet で System.Memory を追加します。NuGet で探す際に [プレリリースを含める]チェック を ON にしないと出てこないので注意してください。
var ary = Enumerable.Range(1, 10).ToArray();
var span = new Span<int>(ary, 2, 3);
var readonlySpan = (ReadOnlySpan<int>)span;
for (int i = 0; i < readonlySpan.Length; i++)
Console.WriteLine(readonlySpan[i]);
span[0] = 11;
Console.WriteLine(readonlySpan[0]);
ary[2] = 31;
Console.WriteLine(readonlySpan[0]);
Console.ReadKey();
・Span は配列(など)の一部の範囲を切り出して値の参照を持てる
・Sapn を new する際に引数で「2 番目の要素から長さ 3」と指定していますが、for で回した際に確かに「2 番目の要素から 3 つ」が出力された
・最初に作った ary という配列の要素を変更した際に、Span の値も変更されているので確かに参照を持っている
・Span だけでなく ReadOnlySpan という読み取り専用の型も存在する
ちなみにこれ、System.Memory さえ参照すれば、C# のバージョンは関係ないみたいですね。C# 3 に変更しても動作します。
蛇足ですが、Span にある DangerousCreate ってメソッドの名前、惹かれるものがありますよね?
■ readonly struct を試す
readonly struct SA
{
public readonly int PA;
public SA(int a)
{
PA = a;
}
}
struct SB
{
public readonly int PA;
public int PB;
public SB(int a, int b)
{
PA = a;
PB = b;
}
public void Set(SB a) { this = a; }
}
・readonly struct は readonly なメンバーしか持てない
・保持する値が変更されない(値が変更可能になる定義が禁止される)
■ in parameters / ref readonly returns を試す
struct SB
{
public int PA;
public void Set(int a) => this.PA = a;
}
static ref readonly SB MyMethod(in SB a)
{
Console.WriteLine(a.PA);
a.Set(12);
Console.WriteLine(a.PA);
return ref a;
}
static void Main(string[] args)
{
var sb1 = new SB { PA=10 };
ref readonly var sb2 = ref MyMethod(sb1);
Console.WriteLine(sb1.PA);
Console.WriteLine(sb2.PA);
sb1.Set(13);
Console.WriteLine(sb1.PA);
Console.WriteLine(sb2.PA);
sb2.Set(14);
Console.WriteLine(sb1.PA);
Console.WriteLine(sb2.PA);
Console.ReadKey();
}
これはちょっとルールが多くて複雑です。
とりあえずやりたいこととしては
・構造体を参照で渡してパフォーマンスを上げたいが、メソッド内/ return 先で書き換えられたくない場合に使う
・構造体を参照で渡しつつ、読み取り専用に制限できる
■ private protected を試す
次の二つの名前空間は別アセンブリにあるとします。
namespace ClassLibrary1
{
public class Class1
{
private protected void MyMethod() {; }
}
public class Class3 : Class1
{
void MyMethod2() { base.MyMethod(); }
}
}
namespace AnotherAssemblyClass
{
class AnotherAssemblyClass : ClassLibrary1.Class1
{
void MyMethod3()
{
}
}
}
・同一アセンブリ内でのみアクセスできる
■ Non-trailing named arguments を試す
static void MyMethod(int a, int b, int c, int d)
{
;
}
static void Main(string[] args)
{
MyMethod(1, 2, c:3, 4);
MyMethod(1, 2, d: 3, c:4);
MyMethod(d:1, c:2, b: 3, a:4);
}
・位置が順番とあっていれば、末尾でなくても引数に名前を付けられる
その他の 7.2 の機能
とりあえず、リリースノートに書かれている機能は確かに確認できそうです。
その他のリリースノートに書かれていない機能は、また後日試してみます。