rksoftware

Visual Studio とか C# とかが好きです

Visual Studio (Win) で C# 7.2 が使えるらしいので試してみた (その他の機能)

Visual Studio (Win) で C# 7.2 が使えるらしいので試して見ました。

Visual Studio 2017 15.5 Preview 4 が必要らしいのでインストールします。
今の Visual Studio は同一メジャーバージョン/エディションでも複数インストールできるのではかどりますね。

前回は、リリースノートに載っている機能を試してみました。

今回は、それ以外の機能を試してみます。

参考

今回のメニュー

・Allow digit separator after 0b or 0x
・conditional ref operator
・ref extension methods on structs

■ C# 7.2 の設定

プロジェクトを新規に作成したらいつもの手順で、C# 7.2 を使えるように設定します。
プロジェクト > ××のプロパティ > ビルド > (右下の方の)[詳細設定]ボタン > 全般の[言語バージョン] を **C# 7.2** に設定 これで、C# 7.2 が使えるはずです。

■ Allow digit separator after 0b or 0x

// C# 7.1 で書ける
readonly int A = 0x1_2345;
readonly int B = 0b1_0101;

// C# 7.2 でないとエラー
readonly int CS72A = 0x_1_2345;
readonly int CS72B = 0b_1_0101;

0x0b の直後に _ を書けるようになった

■ conditional ref operator

{
    var a = 10;
    var b = 20;
    ref var c = ref (true ? ref a : ref b);
    a = 11;
    b = 21;
    Console.WriteLine($"a:{a} b:{b} c:{c}");    // a: 11 b: 21 c: 11 と出力される
}
{
    var a = 10;
    var b = 20;
    ref var c = ref (false ? ref a : ref b);
    a = 12;
    b = 22;
    Console.WriteLine($"a:{a} b:{b} c:{c}");    // a: 12 b: 22 c: 22 と出力される
}
{
    var a = 10;
    var b = 20;
    (true ? ref a : ref b) = 13;
    Console.WriteLine($"a:{a} b:{b}");    // a: 13 b: 20 と出力される
}
{
    var a = 10;
    var b = 20;
    (false ? ref a : ref b) = 24;
    Console.WriteLine($"a:{a} b:{b}");    // a: 10 b: 24 と出力される
}

Console.ReadKey();

・三項演算子で参照(ref)を返せるようになった
・参照が返るので、上記例の 3、4 つ目の様に結果に対して値を代入できる
見た目気持ち悪いけれど、とても便利そうですね

ちなみにこの機能、 C# 7.0 以上なら 7.2 でなくても使えます。 ※Visual Studio 2017 15.5 Preview 4 である必要はあります。

■ ref extension methods on structs

// 構造体
struct SA
{
    public int PA;
    public int PB;
}

// 拡張メソッド
static class SAExtensions
{
    public static int GetPA(in this SA sa)
    {
        //return sa.PA = 11; ← sa は読み取り専用のためエラー
        return sa.PA;
    }
    public static int GetPB(ref this SA sa) => sa.PB = 22; // sa は参照なので値を変更できる
    // public static int GetPB(in this SA sa) => sa.PB;  ← in と ref だけが異なる overload は定義できない
}

class Program
{
    static void Main(string[] args)
    {
        var sa = new SA { PA = 10, PB = 20 };
        Console.WriteLine(sa.GetPA());  // 10 が出力される
        Console.WriteLine(sa.GetPB());  // 22 が出力される
        Console.WriteLine(sa.PB);       // 22 が出力される

        Console.ReadKey();
    }
}

・拡張メソッドの this 引数を参照にできる
※ここで出てきた in キーワードについては前回を参照してください。

7.2 の機能

とりあえず、7.2 の機能は確かに確認できそうです。
ただ、C# 7.2 の機能はパフォーマンスを向上できる機能が多くなっています。
そこまでパフォーマンスを意識しなくていい世界で生きているので意識しないと使いこなすのが難しそうです。頑張って覚えないといけないですね。