What's New in C# 7、New Features in C# 7.0 をベースに、C# 6 と比較してコードがどう変わるのかを記載しています。
1. out
変数 (out
variables)
old
int number;
if (int.TryParse(input, out number)) {
Console.WriteLine(number);
}

2. パターンマッチング (Pattern matching)
is
式でのパターン (is
expressions with patterns)
old
public static int Count<T>(this IEnumerable<T> source) {
if (source == null) throw new ArgumentNullException(nameof(source));
if (source is ICollection<T>) {
return ((ICollection<T>)source).Count;
}
if (source is ICollection) {
return ((ICollection)source).Count;
}
...
}


3. タプル (Tuples)
old
var range = Range(numbers);
Console.WriteLine($"min:{range.Item1}, max:{range.Item2}");
...
public static Tuple<int, int> Range(IEnumerable<int> source) {
int min = default(int);
int max = default(int);
...
return Tuple.Create(min, max);
}

4. 分解 (Deconstruction)
old
var point = new Point(1, 2);
var a = point.X;
var b = point.Y;

5. 破棄 (Discards)
old
int workerThreads, tmp;
ThreadPool.GetAvailableThreads(out workerThreads, out tmp);

6. ローカル関数 (Local functions)
old
public static IEnumerable<int> OddSequence(int start, int end) {
// 引数の評価処理も反復子に含まれている為、実際に反復処理が行われるまで評価が遅延されてしまう。
if (start < 0) throw new ArgumentOutOfRangeException(nameof(start));
if (end <= start) throw new ArgumentException("start must be less than end.");
for (int i = start; i <= end; i++) {
if (i % 2 == 1) {
yield return i;
}
}
}

return GetOddSequenceEnumerator();
IEnumerable<int> GetOddSequenceEnumerator() {
for (int i = start; i <= end; i++) {
if (i % 2 == 1) {
yield return i;
}
}
}
}
ローカル関数によって、評価のタイミングの異なる処理を効果的に分割できます。
## 7. [数値リテラルの改善 (Numeric literal syntax improvements)](https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-7#numeric-literal-syntax-improvements)
### バイナリリテラル (Binary Literals)
```csharp:old
var mask = 0x3b;

桁区切り (Digit Separators)
old
var d = 1000000;
var x = 0x504B0304;

8. ref
戻り値と ref
ローカル変数 (ref
returns and locals)
old
void Convert(System.Drawing.Point[] points) {
for(var i = 0; i < points.Length; i++) {
var p = points[i];
p.X += 10;
p.Y += 20;
points[i] = p;
}
}

9. 一般化された async の戻り値の型と ValueTask (Generalized async return types and ValueTask)
old
private int? _cached;
public async Task<int> GetValueAsync() {
if (_cached == null) {
_cached = await Task.Run(() => 123);
}
return _cached.Value;
}

public async ValueTask GetValueAsync() {
if (_cached == null) {
_cached = await Task.Run(() => 123);
}
return _cached.Value;
}
戻り値が値型になった事で、参照型(`Task`)のインスタンス化による追加のメモリ割り当てを回避する事が可能となりました。
## 10. [式形式のメンバーの拡充 (More expression-bodied members)](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/statements-expressions-operators/expression-bodied-members)
```csharp:old
class Person {
private string _name;
// コンストラクター
public Person(string name) {
_name = name;
}
// ファイナライザー
~Person() {
Console.Error.WriteLine("Finalized");
}
// プロパティ
public string Name {
get { return _name; }
set { _name = value; }
}
}

// コンストラクター
public Person(string name) => _name = name;
// ファイナライザー
~Person() => Console.Error.WriteLine("Finalized");
// プロパティ
public string Name {
get => _name;
set => _name = value;
}
}
## 11. [`throw` 式 (`throw` Expressions)](https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/throw#the-throw-expression)
```csharp:old
class Person {
public string Name { get; }
public Person(string name) {
if (name == null) throw new ArgumentNullException(nameof(name));
Name = name;
}
public string GetFirstName() {
var parts = Name.Split(' ');
if (parts.Length <= 0) {
throw new InvalidOperationException("No name!");
}
return parts[0];
}
public string GetLastName() {
throw new NotImplementedException();
}
}

// null 合体演算子
public Person(string name) {
Name = name ?? throw new ArgumentNullException(nameof(name));
}
// 条件演算子
public string GetFirstName() {
var parts = Name.Split(' ');
return (parts.Length > 0) ? parts[0] : throw new InvalidOperationException("No name!");
}
// 式形式のラムダ
public string GetLastName() => throw new NotImplementedException();
}
## For more information
- [What's New in C# 7 - C# Guide | Microsoft Docs](https://docs.microsoft.com/ja-jp/dotnet/csharp/whats-new/csharp-7)
- [New Features in C# 7.0 | .NET Blog](https://blogs.msdn.microsoft.com/dotnet/2017/03/09/new-features-in-c-7-0/)