.net column

.NET開発者のためのブログメディア
データベースのイメージ

C# 8の使い方を紹介!|C# 8の新機能を正しく使いこなそう

2020年10月29日
SE
C# 8はいままのバージョンとどこが変わりましたか。
PM
構造体を部分的に読み取り専用にできるようになったり、インターフェイスが大幅にパワーアップしたほか、多くの新しい機能が追加、変更されました。

C# 8の色々な新機能を紹介します

C# 8は2019年9月にリリースされたC#のバージョンです。.NET Core 3.xと.NET Standard 2.1以降でサポートされています。それでは早速、C# 8の新機能を解説して行きましょう。

 

まずC# 8では構造体のメンバーにreadonlyを使用できるようになりました。

 

以下のサンプルをご覧ください。

 

struct Human
{
public readonly string Name;
public int Age;

 

public Human(string name)
{
Name = name;
Age = 0;
}

 

public readonly string GetNameAndAge()
{
return Name + “”は”” + Age + “”歳です。””;
}

 

public void AddAge()
{
Age++;
}
}

 

class Program
{
public static void Main()
{
Human h = new Human(“”太郎””);
h.AddAge();
Console.WriteLine(h.GetNameAndAge());
}
}

構造体を部分的に読み取り専用にできるようになった

上のサンプルを実行すると、以下のように表示されます。

 

太郎は1歳です。

 

構造体のHumanのAgeは変更できますが、Nameはreadonlyのためコンストラクタ以外での変更はできません。またGetNameAndAgeメソッドも内容を書き換えないためreadonlyにしています。このようにreadonlyを使うことで、フィールドを間違って変更するようなバグを防ぐことができます。

 

C# 8以前はreadonly structのように全体を読み取り専用にすることはできましたが、このように部分的に読み取り専用にすることはできませんでした。C# 8から構造体をより安全に活用することができます。

インターフェイスが大幅にパワーアップ

C# 8ではinterfaceの機能が大幅に拡張されました。以下をご覧ください。

 

interface IWalk
{
public void Walk()
{
DispMessage();
}

 

private void DispMessage()
{
Console.WriteLine(“”歩けません。””);
}

 

static void DispSetsumei()
{
Console.WriteLine(“”これは歩けるかどうかについてのインターフェイスです。””);
}
}

 

class Human : IWalk
{
public void Walk()
{
Console.WriteLine(“”歩きます。””);
}
}

 

class Flower : IWalk
{
}

 

class Program
{
public static void Main()
{
IWalk.DispSetsumei();
IWalk h = new Human();
h.Walk();
IWalk f = new Flower();
f.Walk();
}
}

デフォルト実装・private・staticが使用可能になった

上のサンプルを実行すると以下のように表示されます。

 

これは歩けるかどうかについてのインターフェイスです。
歩きます。
歩けません。

 

IWalkインターフェイスのWalkには、DispMessageメソッドを呼ぶデフォルトの処理が記述されています。これが新機能で、従来のインターフェイスに記述できるのは中身のないメソッド名のみでした。

 

そしてDispMessageはprivateになっています。これも新機能で、インターフェイスのデフォルト処理内でprivateメソッドを使えます。またDispSetsumeiメソッドがstaticなのも新機能です。

インターフェイスと抽象クラスの差はかなり縮まった

インターフェイスにstaticが使用できるようになったことで、IWalk.DispSetsumei();のようにインスタンスを生成せずにインターフェイスのメソッドを使えるようになりました。

 

また、以下のについてですが、FlowerクラスはWalkメソッドがありません。その場合、IWalkのWalkメソッドのデフォルト実装が呼び出されます。これによりインターフェイスにメソッドの追加をしやすくなりました。

 

IWalk f = new Flower();
f.Walk();

 

C# 8からインターフェイスと抽象クラス(abstract class)との差は「フィールドを持てないが、多重継承できる」くらいに縮まったのです。

switch文の改善

C# 8ではswitch文を新たな書き方ができます。以下のようなswitch文を、

 

int i = 0;
string str = null;
switch (i)
{
case 0:
str = “”0です。””;
break;
case 1:
str = “”1です。””;
break;
case 2:
str = “”2です。””;
break;
}
Console.WriteLine(str);

 

以下のように書くことができます。とてもコンパクトにできます。

 

int i = 0;
string str = i switch {
0 => “”0です。””,
1 => “”1です。””,
2 => “”2です。””,
};
Console.WriteLine(str);

using文の改善

C#では以下のようにusing文で、ファイルCloseなどの後処理を行うことができます。

 

using (var file = new System.IO.StreamWriter(“”c:\\test\\test.txt””))
{
file.Write(“”test””);
}

 

C# 8からは以下のように変数の前にusingを付けて宣言するだけで、そのローカル変数のあるメソッドを抜けたら後処理を行ってくれるようになりました。

 

using var file = new System.IO.StreamWriter(“”c:\\test\\test.txt””);
file.Write(“”test””);

ローカル関数でstaticを使用できる

C#はメソッドの中でラムダ式を使ったローカル関数を使用できますが、C# 8からは以下のように、staticを付けて外部の変数にアクセスしないことを明示できるようになりました。

 

public static void Main()
{
DispVal(3);
static void DispVal(int val) => Console.WriteLine(val);
}

 

以下のローカル関数DispAddValは外部の変数aを使用しているのでstaticにできません。staticがあるかないかで外部変数を使っているかどうかが明確になります。

 

public static void Main()
{
int a = 2;
DispAddVal(3);
void DispAddVal(int val) => Console.WriteLine(val + a);
}

null許容参照型を追加してnull禁止モードを実現

C#にはnull許容値型という機能があり、int?とすれば基本型でもnullを使えるようになります。C# 8からは以下のように参照型のクラス変数でも、nullを許容するか許容しないかを選択できるようになりました。

 

#nullable enable
string str1 = null; // 警告が出る
string? str2 = null; // 警告は出ない
#nullable disable

 

#nullable enableの後では、str1はnullなので警告が出ます。nullを禁止できるということです。string?はnull許容参照型のため警告が出ません。その後の#nullable disableでnull禁止を解除できます。

 

#nullable enableをいちいち記述するのではなく、全体をnull禁止にしたいならば、プロジェクトのcsprojファイルに以下を追加すれば可能になります。

 

<Nullable>enable</Nullable>

null合体割り当てで上書き防止

C# 8ではnull合体割り当てという機能が追加されました。以下の??=がそれです。

 

string str = “”あああ””;
str ??= “”いいい””; // strがnullではないので代入されない
Console.WriteLine(str);
str = null;
str ??= “”いいい””; // strがnullなので代入される
Console.WriteLine(str);

 

実行すると以下になります。??=を使うことで左辺がnullでない場合は代入しないという上書き防止ができます。

 

あああ
いいい

範囲アクセスで切り取りができる

C# 8からは..を使った範囲アクセスができるようになりました。

 

int[] ary = new[] { 0, 1, 2, 3, 4 };

 

int[] range1 = ary[1..3];
foreach (int i in range1)
{
Console.Write(i);
}

 

Console.WriteLine();

 

int[] range2 = ary[1..^1];
foreach (int i in range2)
{
Console.Write(i);
}

 

実行すると以下になります。a..bでa番目からb番目の前まで、a..^bでa番目から後ろからb番目までになります。

 

12
123

SE
確かに多くの機能が追加されたり、変更されましたね。
PM
是非チェックして新しい時代のC#プログラミングにチャレンジしましょう。

C# 8の機能を使いこなそう

以上、C# 8の主な新機能を紹介しました。特にインターフェイスが大きな変更です。C# 8のインターフェイスでC#のプログラミングは大きく変わります。是非使いこなして差をつけましょう。


.NET分野でのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

求人一覧

また、直接のエントリーも受け付けております。

エントリー(応募フォーム)