Полное руководство по языку программирования С# 14 и платформе .NET 10 / Pattern matching

Паттерн свойств

Начальный ⏱ 5 мин чтения 👁 2 🕓 обновлено 11.08.2026

Паттерн свойств позволяет сравнивать со значениями определенных свойств объекта. Например, пусть у нас будет следующий класс:


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

Например, в зависимости от языка пользователя выведем ему определенное сообщение, применив паттерн свойств:


Person tom = new Person { Language = "english", Status = "user", Name = "Tom" };
Person pierre = new Person { Language = "french", Status = "user", Name = "Pierre" };

SayHello(tom);		// Hello
SayHello(pierre);	// Salut

void SayHello(Person person)
{
    if(person is Person { Language: "french" })
    {
        Console.WriteLine("Salut");
    }
    else
    {
        Console.WriteLine("Hello");
    }
}

Здесь метод SayHello в качестве параметра принимает объект Person и сопоставляет его с некоторым паттерном. В качестве паттерна выступает выражение Person { Language: "french" }. То есть параметр person должен представлять объект Person, у которого значение свойства Language равно "french".

При этом можно задействовать набор свойств. Например, добавим проверку по свойству Status:


Person tom = new Person { Language = "english", Status = "user", Name = "Tom" };
Person pierre = new Person { Language = "french", Status = "user", Name = "Pierre" };
Person admin = new Person { Language = "english", Status = "admin", Name = "Admin" };

SayHello(admin);    // Hello, admin
SayHello(tom);      // Hello
SayHello(pierre);   // Salut

void SayHello(Person person)
{
    if(person is Person { Language: "english", Status: "admin" })
    {
        Console.WriteLine("Hello, admin");
    }
    else if (person is Person { Language: "french"})
    {
        Console.WriteLine("Salut");
    }
    else
    {
        Console.WriteLine("Hello");
    }
}

Теперь выражение if проверяет, соответствует ли параметр person объекту Person, у которого свойства Language и Status имеют определенные значения.

Подобным образом можно применять паттерн свойств в конструкции switch:


string GetMessage(Person? p) => p switch
{
    { Language: "english" } => "Hello!",
    { Language: "german", Status: "admin" } => "Hallo, admin!",
    { Language: "french" } => "Salut!",
    { } => "undefined",
    null => "null"       // если Person p = null
};

Паттерны свойств предполагают использование фигурных скобок, внутри которых указываются свойства и через двоеточие их значение {свойство: значение}. И со значением свойства в фигурных скобках сравнивается свойство передаваемого объекта. При этом в фигурных скобках мы можем указать несколько свойств и их значений { Language: "german", Status: "admin" } - тогда свойства передаваемого объекта должны соответствовать всем этим значениям.

Можно оставить пустые фигурные скобки, как в последнем случае { } => "undefined!" - передаваемый объект будет соответствовать пустым фигурным скобкам, если он не соответствует всем предыдущим значениям, или например, если его свойства не указаны или имеют значение null.

То есть в данном случае, если у объекта Person p выполняется равенство Language = "english", будет возвращаться строка "Hello!".

Если у объекта Person p одновременно выполняются два равенства Language = "german" и Role="admin", будет возвращаться строка "Hallo, admin!".

Если у объекта Person p выполняется равенство Language = "french", будет возвращаться строка "Salut!".

Если объект Person будет сопоставляться с пустыми фигурными скобками {}, и будет возвращаться строка "undefined".

Последняя проверка проверяет значение на null.

Применение:


Person pierre = new Person { Language = "french", Status = "user", Name = "Pierre" };
string message = GetMessage(pierre);
Console.WriteLine(message);     // Salut!

Person tomas = new Person { Language = "german", Status = "admin", Name = "Tomas" };
Console.WriteLine(GetMessage(tomas));     // Hallo, admin!

Person pablo = new Person { Language = "spanish", Status = "user", Name = "Pablo" };
Console.WriteLine(GetMessage(pablo));     // undefined

Console.WriteLine(GetMessage(null));     // null

Кроме того, мы можем определять в паттерных свойств переменные, передавать этим переменным значения объекта и использовать при возвращении значения:


string GetMessage(Person? p) => p switch
{
	{ Language: "german", Status: "admin" } => "Hallo, admin!",
	{ Language: "french", Name: var name } => $"Salut, {name}!",
	{ Language: var lang} => $"Unknown language: {lang}",
	null => "null"
};

Так, подвыражение Name: var name говорит, что надо передать в переменную name значение свойства Name. Затем ее можно применить при генерации выходного значения: => $"Salut, {name}!"

Применение:


Person pierre = new Person { Language = "french", Status = "user", Name = "Pierre" };
string message = GetMessage(pierre);
Console.WriteLine(message);             // Salut, Pierre!

Person tomas = new Person { Language = "german", Status = "admin", Name = "Tomas" };
Console.WriteLine(GetMessage(tomas));     // Hallo, admin!

Person pablo = new Person { Language = "spanish", Status = "user", Name = "Pablo" };
Console.WriteLine(GetMessage(pablo));     // Unknown language: spanish

Person? bob = null;
Console.WriteLine(GetMessage(bob));         // null

Стоит отметить, что начиная с версии C# 10 было упрощено сопоставление со свойствами вложенных объектов. Допустим, у нас есть следующие классы:


class Employee
{
    public string Name { get;}
    public Company Company { get; set; }
    public Employee(string name, Company company)
    {
        Name = name;
        Company = company;
    }

}
class Company
{
    public string Title { get;}
    public Company(string title) => Title = title;
}

Класс Company определяет свойство Title, которое хранит название компании. Класс Employee определяет сотрудника компании и в свойстве Company хранит компанию. Применим паттерн свойств на основе свойств вложенного объекта Company:


var microsoft = new Company("Microsoft");
var google = new Company("Google");
var tom = new Employee("Tom", microsoft);
var bob = new Employee("Bob", google);

PrintCompany(tom);    // 
PrintCompany(bob);    // 

void PrintCompany(Employee employee)
{
    if (employee is Employee { Company:{Title: "Microsoft" } })
    {
        Console.WriteLine($"{employee.Name} works in Microsoft");
    }
    else
    {
        Console.WriteLine($"{employee.Name} works someware");
    }
}

В методе PrintCompany объект employee сопоставляется с паттерном Employee { Company:{Title: "Microsoft" } }. То есть сотрудник компании должен представлять объект Employee, у которого название компании равно "Microsoft"

Однако мы также можем сократить данный паттерн следующим образом:


void PrintCompany(Employee employee)
{
    if (employee is Employee { Company.Title: "Microsoft" })
    {
        Console.WriteLine($"{employee.Name} works in Microsoft");
    }
    else
    {
        Console.WriteLine($"{employee.Name} works someware");
    }
}

Проверь себя

📋 Тест по теме «Паттерн свойств» Тест по теме

Практические задания

Лёгкое Ручная проверка Заполните пропуск в коде (1)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

class _____
{
    public string Name { get; set; } = "";        // имя пользователя
    public string Status { get; set; } = "";     // статус пользователя
    public string Language { get; set; } = "";   // язык пользователя
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (2)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

Person _____ = new Person { Language = "english", Status = "user", Name = "Tom" };
Person pierre = new Person { Language = "french", Status = "user", Name = "Pierre" };

SayHello(tom);		// Hello
SayHello(pierre);	// Salut

void SayHello(Person person)
{
    if(person is Person { Language: "french" })
    {
        Console.WriteLine("Salut");
    }
    else
    {
        Console.WriteLine("Hello");
    }
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (3)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

Person tom = _____ Person { Language = "english", Status = "user", Name = "Tom" };
Person pierre = new Person { Language = "french", Status = "user", Name = "Pierre" };
Person admin = new Person { Language = "english", Status = "admin", Name = "Admin" };

SayHello(admin);    // Hello, admin
SayHello(tom);      // Hello
SayHello(pierre);   // Salut

void SayHello(Person person)
{
    if(person is Person { Language: "english", Status: "admin" })
    {
        Console.WriteLine("Hello, admin");
    }
    else if (person is Person { Language: "french"})
    {
        Console.WriteLine("Salut");
    }
    else
    {
        Console.WriteLine("Hello");
    }
}
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (4)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

string GetMessage(Person? p) => p switch
{
    { _____: "english" } => "Hello!",
    { Language: "german", Status: "admin" } => "Hallo, admin!",
    { Language: "french" } => "Salut!",
    { } => "undefined",
    null => "null"       // если Person p = null
};
Войдите, чтобы отправить решение
Лёгкое Ручная проверка Заполните пропуск в коде (5)
+10 XP

В приведённом ниже фрагменте кода из этого урока пропущено одно слово. Определите его и впишите в поле ответа (без кавычек и пробелов).

Person pierre = new Person { _____ = "french", Status = "user", Name = "Pierre" };
string message = GetMessage(pierre);
Console.WriteLine(message);     // Salut!

Person tomas = new Person { Language = "german", Status = "admin", Name = "Tomas" };
Console.WriteLine(GetMessage(tomas));     // Hallo, admin!

Person pablo = new Person { Language = "spanish", Status = "user", Name = "Pablo" };
Console.WriteLine(GetMessage(pablo));     // undefined

Console.WriteLine(GetMessage(null));     // null
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (1)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

class _____
{
    public string Name { get; set; } = "";        // имя пользователя
    public string Status { get; set; } = "";     // статус пользователя
    public string _____ { get; set; } = "";   // язык пользователя
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Восстановите код по памяти (2)
+20 XP

В этом фрагменте кода урока пропущены два ключевых элемента. Впишите оба пропущенных значения через запятую в порядке появления (например: x, 5).

Person tom = new Person { Language = "english", Status = "user", Name = "Tom" };
Person pierre = new Person { Language = "_____", Status = "user", Name = "Pierre" };

Say_____(tom);		// Hello
SayHello(pierre);	// Salut

void SayHello(Person person)
{
    if(person is Person { Language: "french" })
    {
        Console.WriteLine("Salut");
    }
    else
    {
        Console.WriteLine("Hello");
    }
}
Войдите, чтобы отправить решение
Среднее Ручная проверка Расставьте строки кода в правильном порядке
+20 XP

Строки кода из примера этого урока перемешаны. Впишите их в правильном порядке, каждую строку — с новой строки.

class Person
}
    public string Language { get; set; } = "";   // язык пользователя
{
    public string Name { get; set; } = "";        // имя пользователя
    public string Status { get; set; } = "";     // статус пользователя
Войдите, чтобы отправить решение
Сложное Ручная проверка Объясните и модифицируйте пример из урока «Паттерн свойств»
+30 XP

Опишите своими словами, что делает приведённый пример кода из урока «Паттерн свойств», и предложите одно осмысленное изменение (например, другое входное значение или дополнительное условие). Приведите итоговый код.

class Person
{
    public string Name { get; set; } = "";        // имя пользователя
    public string Status { get; set; } = "";     // статус пользователя
    public string Language { get; set; } = "";   // язык пользователя
}
Войдите, чтобы отправить решение
Сложное Ручная проверка Найдите потенциальную проблему в коде урока «Паттерн свойств»
+30 XP

Изучите приведённый фрагмент кода и опишите, при каких входных данных или условиях он может сработать не так, как ожидается (граничный случай, отсутствие проверки и т.п.). Предложите исправленный вариант.

Person tom = new Person { Language = "english", Status = "user", Name = "Tom" };
Person pierre = new Person { Language = "french", Status = "user", Name = "Pierre" };

SayHello(tom);		// Hello
SayHello(pierre);	// Salut

void SayHello(Person person)
{
    if(person is Person { Language: "french" })
    {
        Console.WriteLine("Salut");
    }
    else
    {
        Console.WriteLine("Hello");
    }
}
Войдите, чтобы отправить решение
Мини-проект Ручная проверка Мини-проект по теме «Паттерн свойств»
+50 XP

Соберите небольшую программу, которая последовательно демонстрирует ключевые идеи урока. Программа должна быть рабочей и содержать минимум два самостоятельно написанных фрагмента, а не просто копию примера из урока.

Войдите, чтобы отправить решение
Домашнее задание Ручная проверка Домашнее задание по теме «Паттерн свойств»
+25 XP

Напишите собственную небольшую программу, применяющую материал темы «Паттерн свойств». Используйте не менее одной конструкции, показанной в примерах урока. Прикрепите код решения и краткое описание того, что он делает.

Войдите, чтобы отправить решение

Обсуждение (0)

Войдите, чтобы оставить комментарий.