SlideShare a Scribd company logo
(ゲームじゃない方の)
Switchで遊びたい話
masanori_msl@ .NET 5リリース記念 C# Tokyo イベント
About me
 Name:Masui Masanori
 Work:無茶ぶり処理班
 Twitter:https://twitter.com/masanori_msl
 Blog:http://mslgt.hatenablog.com/
https://dev.to/masanori_msl
※なおゲーム機の方は持ってません
今回のお話
C# 7以降でSwitchが
色々パワーアップしてるらしい
...ので試してみた
いままで(定数パターン)
class Program
{
static void Main(string[] args)
{
int id = 1;
switch(id)
{
case 0:
Console.WriteLine("Id was 0");
break;
case 1:
Console.WriteLine("Id was 1");
break;
default:
Console.WriteLine("Not found");
break;
}
}
}
これが実行される
定数を条件として処理を分岐
新しく追加されたもの(型パターン)
public record RecordSample(int Id, string Name);
static void Main(string[] args)
{
RecordSample r = new (3, "Hello");
Play((object)r);
}
private static void Play(object target)
{
switch(target)
{
case RecordSample r:
Console.WriteLine($"Record Id: {r.Id} Name: {r.Name}");
break;
default:
Console.WriteLine("Not found");
break;
}
}
これが実行される
• 型を条件として処理を分岐。変換が可能ならその分岐の処理が実行される + インスタンス生成
• 定数パターンと型パターンは混在できる
型パターンはwhenでさらに細分化できる
private static void Play(object target)
{
switch(target)
{
case RecordSample r when r.Id < 0:
Console.WriteLine($"Record1 Id: {r.Id} Name: {r.Name}");
break;
case RecordSample r when r.Id >= 1:
Console.WriteLine($"Record2 Id: {r.Id} Name: {r.Name}");
break;
case RecordSample r:
Console.WriteLine($"Record Id: {r.Id} Name: {r.Name}");
break;
default:
Console.WriteLine("Not found");
break;
}
}
これが実行される
変換が可能 + when の条件に合致すればその分岐の処理が実行される
さらに
C# 8からはさらにswitch式が登場
いままで(switch文)
static void Main(string[] args)
{
int id = 1;
string message = GetMessage(id);
}
private static string GetMessage(int id)
{
switch(id)
{
case 0:
return "ID was 0";
case 1:
return "ID was 1";
default:
return "Other";
}
}
これが実行される
switch式を使う
static void Main(string[] args)
{
int id = 1;
string message = id switch
{
0 => "ID was 0",
1 => "ID was 1",
_ => "Other"
};
}
これが実行される
• 使えるのはswitch文と同様定数パターンと型パターン
• 初見だとびっくりする(した)が、三項演算子やNull合体演算子を考えると納得できる気が
疑問
whenをたくさん使うと
インスタンスもたくさん作られる?
先ほどのコード
private static void Play(object target)
{
switch(target)
{
case RecordSample r when r.Id < 0:
Console.WriteLine($"Record1 Id: {r.Id} Name: {r.Name}");
break;
case RecordSample r when r.Id >= 1:
Console.WriteLine($"Record2 Id: {r.Id} Name: {r.Name}");
break;
case RecordSample r:
Console.WriteLine($"Record Id: {r.Id} Name: {r.Name}");
break;
default:
Console.WriteLine("Not found");
break;
}
}
target が RecordSample に変換できて、かつ Id = 0 だった場合、インスタンスは3つ作られる?
答え
生成されるインスタンスは一つ
どう実行されるのか
VS Code拡張版ILSpy先生に聞いてみた
(https://marketplace.visualstudio.com/items?itemName=icsharpcode.ilspy-vscode)
こんな風になっているらしい
private static void Play(object target)
{
RecordSample recordSample = target as RecordSample;
if ((object)recordSample != null)
{
if (recordSample.Id < 0)
{
Console.WriteLine($"Record1 Id: ~省略~
return;
}
RecordSample recordSample2 = recordSample;
if (recordSample2.Id >= 1)
{
Console.WriteLine($"Record2 Id: ~省略~
return;
}
RecordSample recordSample3 = recordSample;
Console.WriteLine($"Record Id: ~省略~
}
~省略~
詳しくはWebで
パターン マッチング - C# ガイド | Microsoft Docs
https://docs.microsoft.com/ja-jp/dotnet/csharp/pattern-matching
switch 式 - C# リファレンス | Microsoft Docs
https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/operators/switch-expression
パターン マッチング - C# によるプログラミング入門 | ++C++; // 未確認飛行 C
https://ufcpp.net/study/csharp/datatype/patterns/
C# 8.0 パターン マッチング | ++C++; // 未確認飛行 C ブログ
https://ufcpp.net/blog/2018/12/cs8patterns/
Do more with patterns in C# 8.0 | .NET Blog
https://devblogs.microsoft.com/dotnet/do-more-with-patterns-in-c-8-0/
C# 8.0 - C# 8.0 でのパターン マッチング | Microsoft Docs
https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2019/may/csharp-8-0-pattern-matching-
in-csharp-8-0
Programming C# 8.0
https://www.oreilly.com/library/view/programming-c-80/9781492056805/
少し遊んでみる
TypeScriptっぽく変換してみたい
どういうことか
TypeScript・・・というかJavaScriptは、
そのClass(or Type or Inteface)と同じプロパティを持っていれば、
同じものとしてふるまうことができる
ということでそれを真似してみる
• RecordSample に直接変換できる場合は変換する
• 変換できない場合でかつ同じプロパティを持っている場合は、
RecordSampleの同名のプロパティに値を入れたインスタンスを作る
変換用のメソッドを作る
public record RecordSample
{
public int Id { get; init; }
public string Name { get; init; } = "";
public RecordSample(int id, string name) { Id = id; Name = name; }
public static bool TryParse(object original, out RecordSample? result)
{
result = null;
var type = original.GetType();
var idValue = type.GetProperty("Id")?.GetValue(original)?.ToString();
var nameValue = type.GetProperty("Name")?.GetValue(original)?.ToString();
if(idValue == null || nameValue == null) { return false; }
if(int.TryParse(idValue, out var id) == false) { return false; }
result = new RecordSample(id, nameValue);
return true;
}
}
case を追加
private static void Play(object target)
{
switch(target)
{
case RecordSample r:
Console.WriteLine($"Record Id: {r.Id} Name: {r.Name}");
break;
case var o when RecordSample.TryParse(o, out var r):
Console.WriteLine($"Property Id: {r!.Id} Name: {r!.Name}");
break;
default:
Console.WriteLine("Not found");
break;
}
}
RecordSampleに変換できず、
かつ同じプロパティを持っていれば
ここが実行されるはず
呼び出し
public class ClassSample
{
public int Id { get; set; }
public string Name { get; set; } = "";
}
static void Main(string[] args)
{
var c = new ClassSample
{
Id = 0,
Name = "Hello"
};
Play((object)c);
}
同じプロパティを持つClassSampleというクラスを作って先ほどのswitchに渡す
結果
Property Id: 0 Name: Hello
疑問
どこで使おう?
便利そうだけれども
• あんまりobjectで渡して型変換ってしない気がする
(ライブラリを作る場合は重宝するかも?)
• switch式の方は細かく使えそうかも
• ClosedXML(https://github.com/closedxml/closedxml)と
組み合わせると良さそう?
Thank you!

More Related Content

PDF
20201127 .NET 5
PDF
Q#基礎 ver1.1
PDF
.NET Core時代のCI/CD
PDF
ゼロから始めるQ#
PDF
テスト駆動で行うネットワーク自動化のすすめ
PDF
(過去バージョン) Q#基礎 ver1.0
PPTX
Modern .NET
PPTX
C# design note sep 2014
20201127 .NET 5
Q#基礎 ver1.1
.NET Core時代のCI/CD
ゼロから始めるQ#
テスト駆動で行うネットワーク自動化のすすめ
(過去バージョン) Q#基礎 ver1.0
Modern .NET
C# design note sep 2014

What's hot (20)

PDF
Road to success System.IO.Compression.ZipArchive Feedback
PPTX
dotnetconfJP2017_netcore2
PPTX
3分で作るストリーム処理基盤~kafka+flink on docker編~
PDF
VSCodeで始めるAzure Static Web Apps開発
PPTX
20170527 inside .NET Core on Linux
PPTX
今から始める、Windows 10&新.NETへの移行戦略
PDF
.NET Coreから概観する.NETのOSSへの取り組み
PDF
hooks riverpod + state notifier + freezed でのドメイン駆動設計
PDF
Bluetoothでgo!
PDF
phpspecで始めるBDD
PPT
20090124shibuya Trac
PDF
linq.js - Linq to Objects for JavaScript
PDF
イケてる技術で品質を担保しつつスピード感のある開発を実現する冴えたやり方
PDF
インフラエンジニアのお仕事(オンプレ)
PDF
Riverpodでテストを書こう
PPTX
C#で速度を極めるいろは
PDF
RTミドルウェアによるロボットプログラミング技術 2.プログラミングの基礎
PDF
Angular ユーザーなら押さえておきたい! TypeScript と Visual Studio Code の基礎と活用
PDF
The History of Reactive Extensions
PPTX
C# 8.0 非同期ストリーム
Road to success System.IO.Compression.ZipArchive Feedback
dotnetconfJP2017_netcore2
3分で作るストリーム処理基盤~kafka+flink on docker編~
VSCodeで始めるAzure Static Web Apps開発
20170527 inside .NET Core on Linux
今から始める、Windows 10&新.NETへの移行戦略
.NET Coreから概観する.NETのOSSへの取り組み
hooks riverpod + state notifier + freezed でのドメイン駆動設計
Bluetoothでgo!
phpspecで始めるBDD
20090124shibuya Trac
linq.js - Linq to Objects for JavaScript
イケてる技術で品質を担保しつつスピード感のある開発を実現する冴えたやり方
インフラエンジニアのお仕事(オンプレ)
Riverpodでテストを書こう
C#で速度を極めるいろは
RTミドルウェアによるロボットプログラミング技術 2.プログラミングの基礎
Angular ユーザーなら押さえておきたい! TypeScript と Visual Studio Code の基礎と活用
The History of Reactive Extensions
C# 8.0 非同期ストリーム
Ad

Similar to (ゲームじゃない方の)switchで遊びたい話 (20)

PPT
「C言語規格&MISRA-C:みんなで楽しいCプログラミング」NGK2013B名古屋合同懇親会2013忘年会昼の部
PPTX
復習も兼ねて!C#6.0-7.0
PDF
C++コミュニティーの中心でC++をDISる
PPTX
MISRA-C2012とISO/IEC 9899:2011 at OSCNagoya2013
PPTX
Unity C#3からC#6に向けて
PPTX
Unimaginable code & commentary
PDF
とあるFlashの自動生成
PDF
今からでも遅くないC#開発
PDF
パターンでわかる! .NET Coreの非同期処理
PDF
よろしい、ならばMicro-ORMだ
PDF
知って得するC#
PDF
Pact言語によるセキュアなスマートコントラクト開発
PPTX
もっと早く知りたかったプログラミング技法9選
PDF
Hello Dark-Side C# (Part. 1)
PDF
Rのデータ構造とメモリ管理
PPT
Inside mobage platform
PDF
わんくま同盟名古屋勉強会18回目 ASP.NET MVC3を利用したHTML5な画面開発~クラウドも有るよ!~
PDF
PHPフレームワーク入門
PDF
20141129-dotNet2015
PPTX
C++の復習
「C言語規格&MISRA-C:みんなで楽しいCプログラミング」NGK2013B名古屋合同懇親会2013忘年会昼の部
復習も兼ねて!C#6.0-7.0
C++コミュニティーの中心でC++をDISる
MISRA-C2012とISO/IEC 9899:2011 at OSCNagoya2013
Unity C#3からC#6に向けて
Unimaginable code & commentary
とあるFlashの自動生成
今からでも遅くないC#開発
パターンでわかる! .NET Coreの非同期処理
よろしい、ならばMicro-ORMだ
知って得するC#
Pact言語によるセキュアなスマートコントラクト開発
もっと早く知りたかったプログラミング技法9選
Hello Dark-Side C# (Part. 1)
Rのデータ構造とメモリ管理
Inside mobage platform
わんくま同盟名古屋勉強会18回目 ASP.NET MVC3を利用したHTML5な画面開発~クラウドも有るよ!~
PHPフレームワーク入門
20141129-dotNet2015
C++の復習
Ad

(ゲームじゃない方の)switchで遊びたい話