Mono 5.0 と C# 7 の Local Functions, Tuples で遊ぶ
Mono 5.0 と C# 7 で遊びます。
まずは、mono のアップグレード。
$ brew upgrade mono
mono のバージョンの確認。
$ mono --version Mono JIT compiler version 5.0.1.1 (2017-02/5077205 Wed May 31 14:47:54 BST 2017) Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
csc
コマンドでコンパイルして実行します。
$ cat a.cs using System; class Program { static void Main() { Console.WriteLine("Hello C# 7"); } } $ csc a.cs Microsoft (R) Visual C# Compiler version 2.0.0.61404 Copyright (C) Microsoft Corporation. All rights reserved. $ mono a.exe Hello C# 7
C# 7 で遊ぶ準備が整いました。
Local Functions
メソッド名と同じ名前のローカル関数を定義できるようです。 以下では、メソッド名と同じ Add, Sub という名前のローカル関数を定義しています。
using System; class Program { static int Add(int a, int b) { int Add(int x, int y) { return x + y; } return Add(a, b); } static int Sub(int a, int b) { int Sub(int x, int y) => x - y; return Sub(a, b); } static void Main() { Console.WriteLine(Add(10, 23)); // 33 Console.WriteLine(Sub(100, 88)); // 12 } }
ローカル関数の引数には、外側のメソッドと同じ引き数名は付けられないようです。
using System; class Program { static int Add1(int n) { // コンパイルエラー: 引数名 n は外側のメソッドで使われている int Add1(int n) => n + 1; return Add1(n); } static void Main() { } }
$ csc a.cs a.cs(6,22): error CS0136: A local or parameter named 'n' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter
Tuples
using System; class Program { static void Main() { var t = ("Bob", 10); Console.WriteLine($"{t.Item1} {t.Item2}"); // Bob 10 var t2 = (Name: "Bob", Age: 10); Console.WriteLine($"{t2.Name} {t2.Age}"); // Bob 10 (string name, int age) = ("Bob", 10); Console.WriteLine($"{name} {age}"); // Bob 10 (string Name, int Age) bob = ("Bob", 10); Console.WriteLine($"{bob.Name} {bob.Age}"); // Bob 10 var (name2, age2) = ("Bob", 10); Console.WriteLine($"{name2} {age2}"); // Bob 10 } }
メソッドの戻り値にも使えますので、複数の値を返すときにわざわざ新しい型を作る必要がなくなります。
using System; class Program { // a を b で割ったときの商と余りを返す static (int Quotient, int Remainder) DivMod(int a, int b) { return (a / b, a % b); } static void Main() { (int q, int r) = DivMod(10, 3); Console.WriteLine($"{q} {r}"); // 3 1 var x = DivMod(11, 3); Console.WriteLine($"{x.Quotient} {x.Remainder}"); // 3 2 var (q2, r2) = DivMod(12, 3); Console.WriteLine($"{q2} {r2}"); // 4 0 } }