Позиционный паттерн


Позиционный паттерн применяется к типу, у которого определен метод деконструктора. Например, определим следующий класс:

class MessageDetails
{
public string Language { get; set; } = ""; // язык пользователя
public string DateTime { get; set; } = ""; // время суток
public string Status { get; set; } = ""; // статус пользователя

public void Deconstruct(out string lang, out string datetime, out string status)
{
lang = Language;
datetime = DateTime;
status = Status;
}
}
Теперь используем позиционный паттерн и в зависимости от значений объекта MessageDetails возвратим определенное сообщение:

string GetWelcome(MessageDetails details) => details switch
{
("english", "morning", _) => "Good morning",
("english", "evening", _) => "Good evening",
("german", "morning", _) => "Guten Morgen",
("german", "evening", _) => "Guten Abend",
(_, _, "admin") => "Hello, Admin",
_ => "Здрасьть"
};
Фактически этот паттерн похож на пример с кортежами выше, только теперь вместо кортежа в конструкцию switch передается объект MessageDetails. Через метод деконструктора мы можем получить набор выходных параметров в виде кортежа и опять же по позиции сравнивать их с некоторыми значениями в конструкции switch.

Применение:

MessageDetails details1 = new MessageDetails { Language = "english", DateTime = "evening", Status = "user" };
string message = GetWelcome(details1);
Console.WriteLine(message); // Good evening

MessageDetails details2 = new MessageDetails { Language = "french", DateTime = "morning", Status = "admin" };
message = GetWelcome(details2);
Console.WriteLine(message); // Hello, Admin
Также мы можем взять значения объекта MessageDetails и использовать их при создании результата метода:

string GetWelcome(MessageDetails details) => details switch
{
("english", "morning", _) => "Good morning",
("english", "evening", _) => "Good evening",
("german", "morning", _) => "Guten Morgen",
("german", "evening", _) => "Guten Abend",
(_, _, "admin") => "Hello, Admin",
(var lang, var datetime, var status) => $"{lang} not found, {datetime} unknown, {status} undefined",
_ => "Здрасьть"
};
В предпоследней инструкции в конструкции switch получаем по позиции значения из MessageDetails в переменные lang, datetime и status и используем их для создания сообщения:

MessageDetails details1 = new MessageDetails
{
Language = "chinese",
DateTime = "night",
Status = "moderator"
};
string message = GetWelcome(details1);
Console.WriteLine(message); // chinese not found, night unknown, moderator undefined