From 74793a209ee7c399a29f90097ea0a7cb9a0c2794 Mon Sep 17 00:00:00 2001 From: konard Date: Sun, 14 Sep 2025 09:28:29 +0300 Subject: [PATCH 1/4] Initial commit with task details for issue #25 Adding CLAUDE.md with task information for AI processing. This file will be removed when the task is complete. Issue: https://github.com/linksplatform/Exceptions/issues/25 --- CLAUDE.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..440d381 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,5 @@ +Issue to solve: https://github.com/linksplatform/Exceptions/issues/25 +Your prepared branch: issue-25-c5f6994d +Your prepared working directory: /tmp/gh-issue-solver-1757831306053 + +Proceed. \ No newline at end of file From 1ca5c3d8d353be52f011c06fbbe7037b8e988af8 Mon Sep 17 00:00:00 2001 From: konard Date: Sun, 14 Sep 2025 09:34:29 +0300 Subject: [PATCH 2/4] Add static extensions support for convenient 'using static' directive usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Added Platform.Exceptions.Static.EnsureStatic with static methods for argument validation - Added Platform.Exceptions.Static.ThrowStatic with static methods for exception throwing - Created comprehensive tests demonstrating static usage patterns - Added example code showing traditional vs static extension usage patterns - Enables cleaner syntax: ArgumentNotNull(obj, "obj") instead of Ensure.Always.ArgumentNotNull(obj, "obj") Resolves issue #25 requesting static extensions support in the programming language. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../StaticExtensionsTests.cs | 74 ++++++++++++ .../Static/EnsureStatic.cs | 82 ++++++++++++++ .../Platform.Exceptions/Static/ThrowStatic.cs | 106 ++++++++++++++++++ 3 files changed, 262 insertions(+) create mode 100644 csharp/Platform.Exceptions.Tests/StaticExtensionsTests.cs create mode 100644 csharp/Platform.Exceptions/Static/EnsureStatic.cs create mode 100644 csharp/Platform.Exceptions/Static/ThrowStatic.cs diff --git a/csharp/Platform.Exceptions.Tests/StaticExtensionsTests.cs b/csharp/Platform.Exceptions.Tests/StaticExtensionsTests.cs new file mode 100644 index 0000000..0cbeaf8 --- /dev/null +++ b/csharp/Platform.Exceptions.Tests/StaticExtensionsTests.cs @@ -0,0 +1,74 @@ +using System; +using Xunit; +using static Platform.Exceptions.Static.EnsureStatic; +using static Platform.Exceptions.Static.ThrowStatic; + +namespace Platform.Exceptions.Tests +{ + public static class StaticExtensionsTests + { + [Fact] + public static void StaticArgumentNotNullTest() + { + // Test static extension usage with using static directive + Assert.Throws(() => ArgumentNotNull(null, "object")); + } + + [Fact] + public static void StaticNotSupportedExceptionTest() + { + // Test static extension usage with using static directive + Assert.Throws(() => NotSupportedException()); + } + + [Fact] + public static void StaticNotImplementedExceptionTest() + { + // Test static extension usage with using static directive + Assert.Throws(() => NotImplementedException()); + } + + [Fact] + public static void StaticArgumentMeetsCriteriaTest() + { + // Test static extension usage with using static directive + Assert.Throws(() => ArgumentMeetsCriteria(5, x => x > 10, "number", "Number must be greater than 10")); + } + + [Fact] + public static void StaticNotSupportedExceptionWithMessageTest() + { + // Test static extension usage with custom message + var exception = Assert.Throws(() => NotSupportedException("Custom message")); + Assert.Equal("Custom message", exception.Message); + } + + [Fact] + public static void StaticArgumentNullExceptionTest() + { + // Test static extension usage for ArgumentNullException + Assert.Throws(() => ArgumentNullException("testParam")); + } + + [Fact] + public static void StaticArgumentExceptionTest() + { + // Test static extension usage for ArgumentException + Assert.Throws(() => ArgumentException("Invalid argument", "testParam")); + } + + [Fact] + public static void StaticNotSupportedExceptionAndReturnTest() + { + // Test static extension usage that returns a value + Assert.Throws(() => NotSupportedExceptionAndReturn()); + } + + [Fact] + public static void StaticNotImplementedExceptionAndReturnTest() + { + // Test static extension usage that returns a value + Assert.Throws(() => NotImplementedExceptionAndReturn()); + } + } +} \ No newline at end of file diff --git a/csharp/Platform.Exceptions/Static/EnsureStatic.cs b/csharp/Platform.Exceptions/Static/EnsureStatic.cs new file mode 100644 index 0000000..73659e0 --- /dev/null +++ b/csharp/Platform.Exceptions/Static/EnsureStatic.cs @@ -0,0 +1,82 @@ +using System; +using System.Runtime.CompilerServices; + +namespace Platform.Exceptions.Static +{ + /// + /// Provides static methods for ensuring contract compliance that can be used with 'using static' directive. + /// Предоставляет статические методы для гарантирования соответствия контракту, которые можно использовать с директивой 'using static'. + /// + public static class EnsureStatic + { + /// + /// Ensures that argument is not null. + /// Гарантирует, что аргумент не нулевой. + /// + /// Type of argument.Тип аргумента. + /// The argument.Аргумент. + /// The argument's name.Имя аргумента. + /// The message of the thrown exception.Сообщение выбрасываемого исключения. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentNotNull(TArgument argument, string argumentName, string message) + where TArgument : class + => Ensure.Always.ArgumentNotNull(argument, argumentName, message); + + /// + /// Ensures that argument is not null. + /// Гарантирует, что аргумент не нулевой. + /// + /// Type of argument.Тип аргумента. + /// The argument.Аргумент. + /// The argument's name.Имя аргумента. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentNotNull(TArgument argument, string argumentName) where TArgument : class + => Ensure.Always.ArgumentNotNull(argument, argumentName); + + /// + /// Ensures that argument is not null. + /// Гарантирует, что аргумент не нулевой. + /// + /// Type of argument.Тип аргумента. + /// The argument.Аргумент. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentNotNull(TArgument argument) where TArgument : class + => Ensure.Always.ArgumentNotNull(argument); + + /// + /// Ensures that the argument meets the criteria. + /// Гарантирует, что аргумент соответствует критерию. + /// + /// Type of argument.Тип аргумента. + /// The argument.Аргумент. + /// A predicate that determines whether the argument meets a criterion.Предикат определяющий, соответствует ли аргумент критерию. + /// The argument's name.Имя аргумента. + /// The message of the thrown exception.Сообщение выбрасываемого исключения. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentMeetsCriteria(TArgument argument, Predicate predicate, string argumentName, string message) + => Ensure.Always.ArgumentMeetsCriteria(argument, predicate, argumentName, message); + + /// + /// Ensures that the argument meets the criteria. + /// Гарантирует, что аргумент соответствует критерию. + /// + /// Type of argument.Тип аргумента. + /// The argument.Аргумент. + /// A predicate that determines whether the argument meets a criterion.Предикат определяющий, соответствует ли аргумент критерию. + /// The argument's name.Имя аргумента. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentMeetsCriteria(TArgument argument, Predicate predicate, string argumentName) + => Ensure.Always.ArgumentMeetsCriteria(argument, predicate, argumentName); + + /// + /// Ensures that the argument meets the criteria. + /// Гарантирует, что аргумент соответствует критерию. + /// + /// Type of argument.Тип аргумента. + /// The argument.Аргумент. + /// A predicate that determines whether the argument meets a criterion.Предикат определяющий, соответствует ли аргумент критерию. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentMeetsCriteria(TArgument argument, Predicate predicate) + => Ensure.Always.ArgumentMeetsCriteria(argument, predicate); + } +} \ No newline at end of file diff --git a/csharp/Platform.Exceptions/Static/ThrowStatic.cs b/csharp/Platform.Exceptions/Static/ThrowStatic.cs new file mode 100644 index 0000000..253f841 --- /dev/null +++ b/csharp/Platform.Exceptions/Static/ThrowStatic.cs @@ -0,0 +1,106 @@ +using System; +using System.Runtime.CompilerServices; + +namespace Platform.Exceptions.Static +{ + /// + /// Provides static methods for throwing exceptions that can be used with 'using static' directive. + /// Предоставляет статические методы для выбрасывания исключений, которые можно использовать с директивой 'using static'. + /// + public static class ThrowStatic + { + /// + /// Throws a new . + /// Выбрасывает новое . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void NotSupportedException() => Throw.A.NotSupportedException(); + + /// + /// Throws a new with the specified message. + /// Выбрасывает новое с указанным сообщением. + /// + /// The message of the thrown exception.Сообщение выбрасываемого исключения. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void NotSupportedException(string message) => throw new NotSupportedException(message); + + /// + /// Throws a new , while returning a value of type. + /// Выбрасывает новое , вовращая при этом значение типа . + /// + /// The type of returned value.Тип возвращаемого значения. + /// A value of type.Значение типа . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TReturn NotSupportedExceptionAndReturn() => Throw.A.NotSupportedExceptionAndReturn(); + + /// + /// Throws a new with the specified message, while returning a value of type. + /// Выбрасывает новое с указанным сообщением, вовращая при этом значение типа . + /// + /// The type of returned value.Тип возвращаемого значения. + /// The message of the thrown exception.Сообщение выбрасываемого исключения. + /// A value of type.Значение типа . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TReturn NotSupportedExceptionAndReturn(string message) => throw new NotSupportedException(message); + + /// + /// Throws a new . + /// Выбрасывает новое . + /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void NotImplementedException() => Throw.A.NotImplementedException(); + + /// + /// Throws a new with the specified message. + /// Выбрасывает новое с указанным сообщением. + /// + /// The message of the thrown exception.Сообщение выбрасываемого исключения. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void NotImplementedException(string message) => throw new NotImplementedException(message); + + /// + /// Throws a new , while returning a value of type. + /// Выбрасывает новое , вовращая при этом значение типа . + /// + /// The type of returned value.Тип возвращаемого значения. + /// A value of type.Значение типа . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TReturn NotImplementedExceptionAndReturn() => Throw.A.NotImplementedExceptionAndReturn(); + + /// + /// Throws a new with the specified message, while returning a value of type. + /// Выбрасывает новое с указанным сообщением, вовращая при этом значение типа . + /// + /// The type of returned value.Тип возвращаемого значения. + /// The message of the thrown exception.Сообщение выбрасываемого исключения. + /// A value of type.Значение типа . + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TReturn NotImplementedExceptionAndReturn(string message) => throw new NotImplementedException(message); + + /// + /// Throws a new . + /// Выбрасывает новое . + /// + /// The argument's name.Имя аргумента. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentNullException(string argumentName) => throw new ArgumentNullException(argumentName); + + /// + /// Throws a new . + /// Выбрасывает новое . + /// + /// The argument's name.Имя аргумента. + /// The message of the thrown exception.Сообщение выбрасываемого исключения. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentNullException(string argumentName, string message) => throw new ArgumentNullException(argumentName, message); + + /// + /// Throws a new . + /// Выбрасывает новое . + /// + /// The message of the thrown exception.Сообщение выбрасываемого исключения. + /// The argument's name.Имя аргумента. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void ArgumentException(string message, string argumentName) => throw new ArgumentException(message, argumentName); + } +} \ No newline at end of file From 04ddd6bf468bdbd0e51e9496168c23c2e4dbcb78 Mon Sep 17 00:00:00 2001 From: konard Date: Sun, 14 Sep 2025 09:34:33 +0300 Subject: [PATCH 3/4] Add usage examples demonstrating static extensions patterns --- examples/StaticExtensionsUsage.cs | 55 +++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 examples/StaticExtensionsUsage.cs diff --git a/examples/StaticExtensionsUsage.cs b/examples/StaticExtensionsUsage.cs new file mode 100644 index 0000000..b1fad05 --- /dev/null +++ b/examples/StaticExtensionsUsage.cs @@ -0,0 +1,55 @@ +using System; +using Platform.Exceptions; +// Using static directive for convenient access +using static Platform.Exceptions.Static.EnsureStatic; +using static Platform.Exceptions.Static.ThrowStatic; + +namespace Platform.Exceptions.Examples +{ + public class StaticExtensionsUsage + { + // Example showing traditional usage vs static extensions usage + public void TraditionalUsage() + { + string parameter = null; + + // Traditional way - using extension methods on root instances + Ensure.Always.ArgumentNotNull(parameter, nameof(parameter)); + + // Throw exceptions the traditional way + Throw.A.NotSupportedException(); + } + + public void StaticExtensionsUsage() + { + string parameter = null; + + // New way - using static imports for cleaner syntax + ArgumentNotNull(parameter, nameof(parameter)); + + // Throw exceptions with static methods + NotSupportedException(); + } + + public void AdvancedStaticUsage() + { + int value = 5; + + // Ensure argument meets criteria using static extension + ArgumentMeetsCriteria(value, x => x > 0, nameof(value), "Value must be positive"); + + // Throw exceptions with custom messages + NotSupportedException("This feature is not yet implemented"); + NotImplementedException("This method needs to be implemented"); + + // Throw ArgumentNullException directly + ArgumentNullException(nameof(value), "Parameter cannot be null"); + } + + public T ExampleMethodWithReturn() + { + // Return type can be inferred while throwing exception + return NotSupportedExceptionAndReturn(); + } + } +} \ No newline at end of file From 54a7b0e01a616ca2732ec616b3f349d6608072c0 Mon Sep 17 00:00:00 2001 From: konard Date: Sun, 14 Sep 2025 09:35:19 +0300 Subject: [PATCH 4/4] Remove CLAUDE.md - Claude command completed --- CLAUDE.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md deleted file mode 100644 index 440d381..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,5 +0,0 @@ -Issue to solve: https://github.com/linksplatform/Exceptions/issues/25 -Your prepared branch: issue-25-c5f6994d -Your prepared working directory: /tmp/gh-issue-solver-1757831306053 - -Proceed. \ No newline at end of file