C#6~7.2までの新機能一覧

C#6~7.2までの新機能について一覧表にしたものです。
先日のわんくま勉強会で登壇した時に作成した資料からの抜粋です。
ちょっとした確認の時などに、便利かと思うので転載しておきます。

このようにまとめてみると、最近は「式を使ったプログラミングに関する機能」と「処理の高速化」に関する追加が多くなってきているように感じますね。

C# 6
読み取り専用の自動プロパティ コンストラクターのみ設定可能な、読み取り専用の自動プロパティの作成 Constructor() {
    Hoge = 123;
}
int Hoge { get; }
自動プロパティの初期化子 自動プロパティの初期値が設定可能に int Hoge { get; } = 123;
ラムダ式を使ったメソッドの実装 メソッドやプロパティの実装にラムダ式が使用可能に int Method() => 1 + 2 + 3;
int Property => 5;
using static クラスを名前空間にインポート using static System.Math;
class Hoge {
    void Main() {
        var max = Max(1, 2);
    }
}
null 条件演算子 メンバーにアクセスする時、オブジェクトが null なら null を返す var x = Hoge?.ToString() ?? “”;
文字列補間 インライン式を使用した書式設定文字列式が記述できる var s = $”年齢は{ x.Age }才です”;
例外フィルター catch でキャッチできる例外を式で指定 try {
}
catch(Exception ex)
    when (e.Message.Contains(“Hoge”)) {
}
nameof 式 名前を文字列として取得 string Method() => nameof(Method);
catch finally ブロックで await 演算子 catch finally ブロックで await 演算子が使用可能に try {
throw new Exception();
}
catch(Exception ex) {
    await HogeAsync();
}
インデックス初期化子 Dictionary などのインデックス付きコレクションの初期化子 var d = new Dictionary<int, string> {
    [4] = “よん”,
    [8] = “はち”
};
コレクション初期化子の拡張メソッド Add拡張メソッドを宣言して、コレクション初期化子を使用できる public static class HogeExtensions {
    public static void Add(this FugaList list, Fuga x)
        => list.AddFuga(x);
}
オーバーロード解決の改善 あいまいなメソッド呼び出しと判断されていた処理の改善 static Task Hoge => Task.FromResult(0);
static void Fuga() => Task.Run(Hoge);
// Func<Task> であることを認識

 

C# 7
out 変数 out の値をメソッドの引数としてインラインで宣言 if (int.TryParse(“1”, out var i))
    return i * i;
タプル 手軽に名前の無い型を作成・コンパイラや IDE ツールでも対応 (int hoge, int fuga) GetValues()
    => (1, 2);
破棄  タプルおよびユーザー定義の型を分解する場合、メソッドを out パラメーターを使用して呼び出す場合に不要な値を破棄 var (_, piyo) = GetValue();
// hoge を破棄
パターン一致 型に基づいて、分岐ロジックを作成 if (piyo is int i) return i * i;

switch(piyo){
    case int i: return i * i;
    case string s: return s + s;
}

ref ローカル変数と戻り値 メソッド引数、ローカル変数、戻り値を参照 void Fuga() {
    var i = 5;
    ref var s = ref Hoge(ref i);
    s = 3;
}
ref int Hoge(ref int a) => ref a;
ローカル関数 関数の入れ子関数を作成 void Hoge {
    var i = 0;
    var j = fuga();
    int fuga() {
        return ++i;
    }
}
式形式のメンバーの追加 式を使用して作成できるメンバーが増えた class Hoge {
    Hoge(int fuga) => Fuga = _fuga;

    ~Hoge() => _fuga = 0;

    int _fuga;
    int Fuga {
        get => _fuga;
        set => _fuga = value;
    }
}

throw 式 throw ステートメントを、式として使用 return hoge ??
    throw new Exception(“fuga”);
一般化された async の戻り値の型 async 修飾されたメソッドの戻り値の型をTask と Task<T> 以外にできる
(ただし、一定の条件を満たす必要がある)
async ValueTask<int> HogeAsync() {
    if (_list.Count < 1000)
        return Hoge();

    return await Task.Run(() => Hoge());
}

数値リテラルの構文の改善 数値定数の表現方法が増えた const int BIN =  0b0001;  // 二進数
const int BIT =  0b0001_0000; // 長いビットパターン
const int DEC = 100_000_000; // 十進数

 

C#7.1
async Mainメソッド アプリケーションのエントリポイントメソッドをasync修飾 static async Task<int> Main()
static async Task Main(string[] args)
defaultリテラル式 型推論できる場合は、defaultの型名を省略 Hoge hoge = default;
// 今までは Hoge hoge = default(Hoge);
bool f = (hoge == default);
推論されたタプル要素の名前 タプル要素の名前を推論 var id = 3;
var title = “hoge”;
var member = (id, title);
// 今までは、(id: id, title: title) と名前を明記

 

C#7.2
値の型による参照セマンティクス 参照渡しに関する構文の強化 ref readonly int Hoge(in Fuga f) {
    // 読取り専用の引数と戻り値
    f.SetValue(19); // 変更されない
    return ref f;
}
void Piyo() {
    var fuga = new Fuga();
    ref readonly var x = ref Hoge(fuga); // x は 読取り専用
    x.SetValue(20); // 変更されない
}
末尾以外の名前付き引数 名前付き引数の後ろに位置引数を指定 HogeMethod(fuga: 3, “piyo”, 1, 2);
数値定数の先頭のアンダースコア 数値リテラルの前にアンダースコア(_) を含められる const int BIN =  0b_0001;  // 二進数
const int BIT =  0b_0001_0000; // 長いビットパターン
private protected アクセス修飾子 internal protected が 「internal」 or 「protected」なら
private protectedは「internal」and 「protected」
private protected int Hoge { get; set; }