From 7cbde57b12c97fd23ade7d879d4f3ed50f72a97d Mon Sep 17 00:00:00 2001 From: ruslan Date: Mon, 19 Jan 2026 23:00:55 +0300 Subject: [PATCH 1/5] feat tasks completed --- .../Tasks/LanguagePatternsTasksTests.cs | 126 ++++++++++++++++++ Advanced/Tasks/AsyncTasks.cs | 48 +++++-- Advanced/Tasks/GenericsTasks.cs | 29 +++- .../DemonstrateDeconstruction.cs | 10 ++ Advanced/Tasks/LanguagePatterns/FullName.cs | 3 + .../Tasks/LanguagePatterns/IComparable.cs | 6 + .../LanguagePatterns/LanguagePatternsTasks.cs | 33 +++-- Advanced/Tasks/LanguagePatterns/Person.cs | 6 + Advanced/Tasks/LanguagePatterns/Product.cs | 11 ++ Advanced/Tasks/PerformanceTasks.cs | 15 ++- 10 files changed, 261 insertions(+), 26 deletions(-) create mode 100644 Advanced.Tests/Tasks/LanguagePatternsTasksTests.cs create mode 100644 Advanced/Tasks/LanguagePatterns/DemonstrateDeconstruction.cs create mode 100644 Advanced/Tasks/LanguagePatterns/FullName.cs create mode 100644 Advanced/Tasks/LanguagePatterns/IComparable.cs create mode 100644 Advanced/Tasks/LanguagePatterns/Person.cs create mode 100644 Advanced/Tasks/LanguagePatterns/Product.cs diff --git a/Advanced.Tests/Tasks/LanguagePatternsTasksTests.cs b/Advanced.Tests/Tasks/LanguagePatternsTasksTests.cs new file mode 100644 index 0000000..06748b2 --- /dev/null +++ b/Advanced.Tests/Tasks/LanguagePatternsTasksTests.cs @@ -0,0 +1,126 @@ +using Advanced.Tasks.LanguagePatterns; +using Xunit; + +namespace Advanced.Tests.Tasks; + +public class LanguagePatternsTasksTests +{ + private readonly LanguagePatternsTasks _sut = new(); + + [Fact] + public void GetObjectTypeNull_ReturnsNull() + { + var result = _sut.GetObjectType(null); + Assert.Equal("Null", result); + } + + [Fact] + public void GetObjectTypeString_ReturnsString() + { + var result = _sut.GetObjectType("hello"); + Assert.Equal("String", result); + } + + [Fact] + public void GetObjectTypeInteger_ReturnsInteger() + { + var result = _sut.GetObjectType(42); + Assert.Equal("Integer", result); + } + + [Fact] + public void GetObjectTypeBoolean_ReturnsBoolean() + { + var result = _sut.GetObjectType(true); + Assert.Equal("Boolean", result); + } + + [Fact] + public void GetObjectTypeDouble_ReturnsDouble() + { + var result = _sut.GetObjectType(3.14); + Assert.Equal("Double", result); + } + + [Fact] + public void GetObjectTypeFloat_ReturnsFloat() + { + var result = _sut.GetObjectType(2.50); + Assert.Equal("Float", result); + } + + [Fact] + public void GetObjectTypeUnknownType_ReturnsUnknown() + { + var result = _sut.GetObjectType(new object()); + Assert.Equal("Unknown", result); + } + + [Fact] + public void CalculateShippingCostStandard_ReturnsFixedCost() + { + var result = _sut.CalculateShippingCost("standard", 10m); + Assert.Equal(10m, result); + } + + [Fact] + public void CalculateShippingCostExpress_ReturnsWeightBasedCost() + { + var result = _sut.CalculateShippingCost("express", 4m); + Assert.Equal(20.0m + 4m * 0.5m, result); + } + + [Fact] + public void CalculateShippingCostUnknownType_ReturnsZero() + { + var result = _sut.CalculateShippingCost("rocket", 1m); + Assert.Equal(0.0m, result); + } + + [Fact] + public void CalculateShippingCostNullType_ReturnsZero() + { + var result = _sut.CalculateShippingCost(null, 1m); + Assert.Equal(0.0m, result); + } + + + [Fact] + public void GetProductStatusNullProduct_ReturnsInvalidMessage() + { + var result = _sut.GetProductStatus(null); + Assert.Equal("Недопустимый товар", result); + } + + [Fact] + public void GetProductStatusPriceOver1000_ReturnsExpensive() + { + var product = new Product { Name = "TV", Price = 1500m, Stock = 5 }; + var result = _sut.GetProductStatus(product); + Assert.Equal("Дорогой товар", result); + } + + [Fact] + public void GetProductStatusZeroStock_ReturnsOutOfStock() + { + var product = new Product { Name = "Phone", Price = 800m, Stock = 0 }; + var result = _sut.GetProductStatus(product); + Assert.Equal("Нет в наличии", result); + } + + [Fact] + public void GetProductStatusNonPositivePrice_ReturnsInvalidPrice() + { + var product = new Product { Name = "Gift", Price = -10m, Stock = 10 }; + var result = _sut.GetProductStatus(product); + Assert.Equal("Некорректная цена", result); + } + + [Fact] + public void GetProductStatusValidProduct_ReturnsAvailable() + { + var product = new Product { Name = "Book", Price = 200m, Stock = 3 }; + var result = _sut.GetProductStatus(product); + Assert.Equal("В наличии", result); + } +} \ No newline at end of file diff --git a/Advanced/Tasks/AsyncTasks.cs b/Advanced/Tasks/AsyncTasks.cs index 9503746..926c43d 100644 --- a/Advanced/Tasks/AsyncTasks.cs +++ b/Advanced/Tasks/AsyncTasks.cs @@ -1,47 +1,75 @@ namespace Advanced.Tasks; +using System.Threading; + public class AsyncTasks { /// /// Задание 2.1: Напишите асинхронный метод, который имитирует загрузку данных. /// Используйте Task.Delay для имитации задержки. /// - public Task LoadDataAsync() + public async Task LoadDataAsync() { - throw new NotImplementedException(); + await Task.Delay(1000); + + return "Load data async..."; } /// /// Задание 2.2: Напишите асинхронный метод, который загружает данные с тайм-аутом. /// Если операция превышает timeout, бросает TimeoutException. /// - public Task LoadDataWithTimeoutAsync(TimeSpan timeout) + public async Task LoadDataWithTimeoutAsync(TimeSpan timeout) { - throw new NotImplementedException(); + using var cts = new CancellationTokenSource(timeout); + + try + { + return await LoadDataWithCancellationAsync(cts.Token); + } + catch (OperationCanceledException) when (cts.Token.IsCancellationRequested) + { + throw new TimeoutException("Operation timeout"); + } } /// /// Задание 2.3: Напишите метод, который выполняет несколько асинхронных операций параллельно /// и возвращает результат, когда все завершатся. /// - public Task ExecuteParallelAsync(IEnumerable> tasks) + public async Task ExecuteParallelAsync(IEnumerable> tasks) { - throw new NotImplementedException(); + var taskList = tasks.ToList(); + + if (taskList.Count == 0) + { + return Array.Empty(); + } + + await Task.WhenAll(taskList); + + return taskList.Select(t => t.Result).ToArray(); } /// /// Задание 2.4: Напишите метод, который поддерживает отмену операции через CancellationToken. /// - public Task LoadDataWithCancellationAsync(CancellationToken cancellationToken) + public async Task LoadDataWithCancellationAsync(CancellationToken cancellationToken) { - throw new NotImplementedException(); + await Task.Delay(1000, cancellationToken); + + cancellationToken.ThrowIfCancellationRequested(); + + return "Data loaded..."; } /// /// Задание 2.5: Напишите метод, который использует ConfigureAwait(false) для избежания deadlock. /// - public Task LoadDataConfigureAwaitAsync() + public async Task LoadDataConfigureAwaitAsync() { - throw new NotImplementedException(); + await Task.Delay(1000).ConfigureAwait(false); + + return "Data loaded..."; } } \ No newline at end of file diff --git a/Advanced/Tasks/GenericsTasks.cs b/Advanced/Tasks/GenericsTasks.cs index e5efb03..ae9fbef 100644 --- a/Advanced/Tasks/GenericsTasks.cs +++ b/Advanced/Tasks/GenericsTasks.cs @@ -1,5 +1,7 @@ namespace Advanced.Tasks; +using System.Collections.Generic; + public class GenericsTasks { /// @@ -9,7 +11,17 @@ public class GenericsTasks /// public T GetFirstElement(IEnumerable collection) { - throw new NotImplementedException(); + if (collection == null) + { + return default(T); + } + + foreach (var item in collection) + { + return item; + } + + return default(T); } /// @@ -17,7 +29,17 @@ public T GetFirstElement(IEnumerable collection) /// public IEnumerable Filter(IEnumerable collection, Func predicate) { - throw new NotImplementedException(); + if (collection == null) + { + return Enumerable.Empty(); + } + + if (predicate == null) + { + return collection; + } + + return collection.Where(predicate); } /// @@ -25,10 +47,11 @@ public IEnumerable Filter(IEnumerable collection, Func predica /// public void Swap(ref T a, ref T b) { - throw new NotImplementedException(); + (a, b) = (b, a); } /// /// Задание 1.4: Создайте generic интерфейс IComparable с методом CompareTo. /// + } \ No newline at end of file diff --git a/Advanced/Tasks/LanguagePatterns/DemonstrateDeconstruction.cs b/Advanced/Tasks/LanguagePatterns/DemonstrateDeconstruction.cs new file mode 100644 index 0000000..663b63b --- /dev/null +++ b/Advanced/Tasks/LanguagePatterns/DemonstrateDeconstruction.cs @@ -0,0 +1,10 @@ +namespace Advanced.Tasks.LanguagePatterns; + +public class DemonstrateDeconstruction +{ + public void Example() + { + var name = new FullName("Евгений", "Березин"); + var (first, last) = name; + } +} \ No newline at end of file diff --git a/Advanced/Tasks/LanguagePatterns/FullName.cs b/Advanced/Tasks/LanguagePatterns/FullName.cs new file mode 100644 index 0000000..fe95a73 --- /dev/null +++ b/Advanced/Tasks/LanguagePatterns/FullName.cs @@ -0,0 +1,3 @@ +namespace Advanced.Tasks.LanguagePatterns; + +public record FullName(string FirstName, string LastName); \ No newline at end of file diff --git a/Advanced/Tasks/LanguagePatterns/IComparable.cs b/Advanced/Tasks/LanguagePatterns/IComparable.cs new file mode 100644 index 0000000..69f3f8f --- /dev/null +++ b/Advanced/Tasks/LanguagePatterns/IComparable.cs @@ -0,0 +1,6 @@ +namespace Advanced.Tasks.LanguagePatterns; + +public interface IComparable +{ + int CompareTo(T compare); +} \ No newline at end of file diff --git a/Advanced/Tasks/LanguagePatterns/LanguagePatternsTasks.cs b/Advanced/Tasks/LanguagePatterns/LanguagePatternsTasks.cs index 123632a..5aebc6e 100644 --- a/Advanced/Tasks/LanguagePatterns/LanguagePatternsTasks.cs +++ b/Advanced/Tasks/LanguagePatterns/LanguagePatternsTasks.cs @@ -8,19 +8,24 @@ public class LanguagePatternsTasks /// /// Задание 4.1: Создайте record Person с свойствами Name и Age. /// - - /// /// Задание 4.2: Создайте класс Product с init-only свойствами. /// - - /// /// Задание 4.3: Используйте pattern matching для определения типа объекта. /// public string GetObjectType(object obj) { - throw new NotImplementedException(); + return obj switch + { + null => "Null", + string => "String", + int => "Integer", + bool => "Boolean", + double => "Double", + float => "Float", + _ => "Unknown" + }; } /// @@ -28,19 +33,29 @@ public string GetObjectType(object obj) /// public decimal CalculateShippingCost(string shippingType, decimal weight) { - throw new NotImplementedException(); + return shippingType?.ToLowerInvariant() switch + { + "standard" => 10m, + "express" => 20.0m + weight * 0.5m, + _ => 0.0m + }; } /// /// Задание 4.5: Создайте record и напишите код (в отдельном классе DemonstrateDeconstruction) использования деконструкции. /// - - /// /// Задание 4.6: Используйте property patterns класса Product для проверки условий. /// public string GetProductStatus(Product product) { - throw new NotImplementedException(); + return product switch + { + null => "Недопустимый товар", + { Price: > 1000 } => "Дорогой товар", + { Stock: 0 } => "Нет в наличии", + { Price: <= 0 } => "Некорректная цена", + _ => "В наличии" + }; } } \ No newline at end of file diff --git a/Advanced/Tasks/LanguagePatterns/Person.cs b/Advanced/Tasks/LanguagePatterns/Person.cs new file mode 100644 index 0000000..f44ee1b --- /dev/null +++ b/Advanced/Tasks/LanguagePatterns/Person.cs @@ -0,0 +1,6 @@ +namespace Advanced.Tasks.LanguagePatterns; + +/// +/// Задание 4.1: record Person с Name и Age. +/// +public record Person(string Name, int Age); \ No newline at end of file diff --git a/Advanced/Tasks/LanguagePatterns/Product.cs b/Advanced/Tasks/LanguagePatterns/Product.cs new file mode 100644 index 0000000..9dc3c1a --- /dev/null +++ b/Advanced/Tasks/LanguagePatterns/Product.cs @@ -0,0 +1,11 @@ +namespace Advanced.Tasks.LanguagePatterns; + +/// +/// Задание 4.2: Класс Product с init-only свойствами. +/// +public class Product +{ + public string Name { get; init; } + public decimal Price { get; init; } + public int Stock { get; init; } +} \ No newline at end of file diff --git a/Advanced/Tasks/PerformanceTasks.cs b/Advanced/Tasks/PerformanceTasks.cs index f24c359..f939875 100644 --- a/Advanced/Tasks/PerformanceTasks.cs +++ b/Advanced/Tasks/PerformanceTasks.cs @@ -7,7 +7,7 @@ public class PerformanceTasks /// public void ReverseArray(T[] array) { - throw new NotImplementedException(); + array.AsSpan().Reverse(); } /// @@ -15,7 +15,14 @@ public void ReverseArray(T[] array) /// public int SumArray(Span span) { - throw new NotImplementedException(); + int sum = 0; + + foreach (int item in span) + { + sum += item; + } + + return sum; } /// @@ -23,11 +30,11 @@ public int SumArray(Span span) /// public object BoxValue(int value) { - throw new NotImplementedException(); + return value; } public int UnboxValue(object value) { - throw new NotImplementedException(); + return (int)value; } } \ No newline at end of file From fa6ea78225f1e99e7f429e8b0ce41c0f17da0b1f Mon Sep 17 00:00:00 2001 From: ruslan Date: Mon, 19 Jan 2026 23:05:32 +0300 Subject: [PATCH 2/5] fix test float fixes --- Advanced.Tests/Tasks/LanguagePatternsTasksTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Advanced.Tests/Tasks/LanguagePatternsTasksTests.cs b/Advanced.Tests/Tasks/LanguagePatternsTasksTests.cs index 06748b2..26f6f38 100644 --- a/Advanced.Tests/Tasks/LanguagePatternsTasksTests.cs +++ b/Advanced.Tests/Tasks/LanguagePatternsTasksTests.cs @@ -45,7 +45,7 @@ public void GetObjectTypeDouble_ReturnsDouble() [Fact] public void GetObjectTypeFloat_ReturnsFloat() { - var result = _sut.GetObjectType(2.50); + var result = _sut.GetObjectType(2.5f); Assert.Equal("Float", result); } From 993ac2b062b6b141914c29c827aad6a978fb5549 Mon Sep 17 00:00:00 2001 From: ruslan Date: Mon, 19 Jan 2026 23:25:47 +0300 Subject: [PATCH 3/5] fix CA --- Advanced/Tasks/GenericsTasks.cs | 6 ------ Advanced/Tasks/LanguagePatterns/Product.cs | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/Advanced/Tasks/GenericsTasks.cs b/Advanced/Tasks/GenericsTasks.cs index ae9fbef..94dcdb2 100644 --- a/Advanced/Tasks/GenericsTasks.cs +++ b/Advanced/Tasks/GenericsTasks.cs @@ -11,11 +11,6 @@ public class GenericsTasks /// public T GetFirstElement(IEnumerable collection) { - if (collection == null) - { - return default(T); - } - foreach (var item in collection) { return item; @@ -53,5 +48,4 @@ public void Swap(ref T a, ref T b) /// /// Задание 1.4: Создайте generic интерфейс IComparable с методом CompareTo. /// - } \ No newline at end of file diff --git a/Advanced/Tasks/LanguagePatterns/Product.cs b/Advanced/Tasks/LanguagePatterns/Product.cs index 9dc3c1a..1317f2b 100644 --- a/Advanced/Tasks/LanguagePatterns/Product.cs +++ b/Advanced/Tasks/LanguagePatterns/Product.cs @@ -5,7 +5,7 @@ namespace Advanced.Tasks.LanguagePatterns; /// public class Product { - public string Name { get; init; } + public string? Name { get; init; } public decimal Price { get; init; } public int Stock { get; init; } } \ No newline at end of file From 3eee3915faff9b0bd718eee47c0fdb8c384c0266 Mon Sep 17 00:00:00 2001 From: ruslan Date: Mon, 19 Jan 2026 23:30:55 +0300 Subject: [PATCH 4/5] fix CA --- Advanced/Tasks/GenericsTasks.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Advanced/Tasks/GenericsTasks.cs b/Advanced/Tasks/GenericsTasks.cs index 94dcdb2..36fa983 100644 --- a/Advanced/Tasks/GenericsTasks.cs +++ b/Advanced/Tasks/GenericsTasks.cs @@ -9,8 +9,13 @@ public class GenericsTasks /// Если коллекция пустая, возвращает default значение типа. /// В каждом задании используйте async/await. /// - public T GetFirstElement(IEnumerable collection) + public T? GetFirstElement(IEnumerable? collection) { + if (collection == null) + { + return default(T); + } + foreach (var item in collection) { return item; @@ -22,7 +27,7 @@ public T GetFirstElement(IEnumerable collection) /// /// Задание 1.2: Напишите generic метод, который фильтрует коллекцию по предикату. /// - public IEnumerable Filter(IEnumerable collection, Func predicate) + public IEnumerable Filter(IEnumerable? collection, Func? predicate) { if (collection == null) { From da89ab238da5311b9c50371114662c92dc3d99f0 Mon Sep 17 00:00:00 2001 From: ruslan Date: Mon, 19 Jan 2026 23:53:23 +0300 Subject: [PATCH 5/5] fix CA --- Advanced/Tasks/LanguagePatterns/LanguagePatternsTasks.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Advanced/Tasks/LanguagePatterns/LanguagePatternsTasks.cs b/Advanced/Tasks/LanguagePatterns/LanguagePatternsTasks.cs index 5aebc6e..4bfce9c 100644 --- a/Advanced/Tasks/LanguagePatterns/LanguagePatternsTasks.cs +++ b/Advanced/Tasks/LanguagePatterns/LanguagePatternsTasks.cs @@ -14,7 +14,7 @@ public class LanguagePatternsTasks /// /// Задание 4.3: Используйте pattern matching для определения типа объекта. /// - public string GetObjectType(object obj) + public string GetObjectType(object? obj) { return obj switch { @@ -31,7 +31,7 @@ public string GetObjectType(object obj) /// /// Задание 4.4: Используйте switch expression для вычисления стоимости доставки. /// - public decimal CalculateShippingCost(string shippingType, decimal weight) + public decimal CalculateShippingCost(string? shippingType, decimal weight) { return shippingType?.ToLowerInvariant() switch { @@ -47,7 +47,7 @@ public decimal CalculateShippingCost(string shippingType, decimal weight) /// /// Задание 4.6: Используйте property patterns класса Product для проверки условий. /// - public string GetProductStatus(Product product) + public string GetProductStatus(Product? product) { return product switch {