スイッチで遊ぶ
イントロ
Cの経度7とCの角8では、“スイッチ”いくつかの新しい機能を得た.
今回は、「スイッチ」を使います.
環境
C≧7(一定パターン)以前
プログラム.cs
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;
}
}
}
定数値のみを使用できます.新しいパターン
型パターン
C≧7の後、タイプを使用できます.
型のパターンで、ターゲットオブジェクトを変換できるかどうかを確認した後、変換されたインスタンスが作成されます.
レコードサンプル.cs
public record RecordSample(int Id, string Name);
プログラム.cs
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;
}
}
結果
Record Id: 3 Name: Hello
タプルパターン
プログラム.cs
static void Main(string[] args)
{
(int Id, string Name) t = (0, "Hello");
Play((object)t);
}
private static void Play(object target)
{
switch(target)
{
case RecordSample r:
Console.WriteLine($"Record Id: {r.Id} Name: {r.Name}");
break;
case (0, "Hello"):
Console.WriteLine("Tuple");
break;
default:
Console.WriteLine("Not found");
break;
}
}
結果
Tuple
プロパティパターン
プログラム.cs
static void Main(string[] args)
{
var r = new RecordSample(1, "Hello");
Play((object)r);
}
private static void Play(object target)
{
switch(target)
{
case RecordSample { Id: 1} r:
Console.WriteLine($"Property pattern 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;
}
}
結果
Property pattern Id: 1 Name: Hello
私もいくつかのより多くのパターンを使用できます.時
新しいパターン(ex . typeパターン)では、より特定の条件に分けることができます.
プログラム.cs
static void Main(string[] args)
{
var r = new RecordSample(1, "Hello");
Play((object)r);
}
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;
}
}
結果
Record2 Id: 1 Name: Hello
スイッチ式
Cでは、“スイッチ式”を追加しました.
私は以下のようにリファクタリングすることができます.
以前
プログラム.cs
static void Main(string[] args)
{
int id = 1;
string message = GetMessage(id);
Console.WriteLine(message);
}
private static string GetMessage(int id)
{
switch(id)
{
case 0:
return "ID was 0";
case 1:
return "ID was 1";
default:
return "Other";
}
}
結果
ID was 1
アフター
プログラム.cs
static void Main(string[] args)
{
int id = 1;
string message = id switch
{
0 => "ID was 0",
1 => "ID was 1",
_ => "Other"
};
Console.WriteLine(message);
}
結果
ID was 1
switch文と同じパターンを使用できます.資源
どのように多くのインスタンスが作成されますか?
質問
たとえば、このコードを実行すると、いくつのインスタンスが生成されますか?
プログラム.cs
static void Main(string[] args)
{
var r = new RecordSample(0, "Hello");
Play((object)r);
}
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:
// Execute here
Console.WriteLine($"Record Id: {r.Id} Name: {r.Name}");
break;
default:
Console.WriteLine("Not found");
break;
}
}
アンサー
つのインスタンスだけが作成されます.
分解杭
私は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: {recordSample.Id} Name: {recordSample.Name}");
return;
}
RecordSample recordSample2 = recordSample;
if (recordSample2.Id >= 1)
{
Console.WriteLine($"Record2 Id: {recordSample2.Id} Name: {recordSample2.Name}");
return;
}
RecordSample recordSample3 = recordSample;
Console.WriteLine($"Record Id: {recordSample3.Id} Name: {recordSample3.Name}");
}
else
{
Console.WriteLine("Not found");
}
}
のようなオブジェクトを変換する
タイプスクリプトでは、インスタンスがRecordSampleクラスと同じプロパティを持つ場合に変換できます.
レコードのサンプル.TS
export class RecordSample {
public id: number = -1;
public name: string = "";
}
プログラム.TS
import { RecordSample } from "./record-sample";
export function main(){
const s = {
id: 1,
name: "Hello"
};
const r: RecordSample = s; // <- OK
}
私もこのようにC .まず、変換するメソッドを追加します.
レコードサンプル.cs
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.ToString(), out var id) == false)
{
return false;
}
result = new RecordSample(id, nameValue);
return true;
}
}
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;
}
}
switch文の“var”はすべての状態をキャッチできます.を返します.
プログラム.cs
static void Main(string[] args)
{
var r = new {
Id = 0,
Name = "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;
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;
}
}
結果
Property Id: 0 Name: Hello
Reference
この問題について(スイッチで遊ぶ), 我々は、より多くの情報をここで見つけました https://dev.to/masanori_msl/c-play-with-switch-5fb0テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol