From 0970a4e9df070e4b2c808f56dbbfdbc8d1641547 Mon Sep 17 00:00:00 2001 From: konard Date: Sun, 14 Sep 2025 13:25:09 +0300 Subject: [PATCH 1/3] Initial commit with task details for issue #5 Adding CLAUDE.md with task information for AI processing. This file will be removed when the task is complete. Issue: https://github.com/linksplatform/Random/issues/5 --- 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..a2462db --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,5 @@ +Issue to solve: https://github.com/linksplatform/Random/issues/5 +Your prepared branch: issue-5-5be42f02 +Your prepared working directory: /tmp/gh-issue-solver-1757845506800 + +Proceed. \ No newline at end of file From 249de9e7f6d846aee96e38652ab0c886795926c5 Mon Sep 17 00:00:00 2001 From: konard Date: Sun, 14 Sep 2025 13:35:59 +0300 Subject: [PATCH 2/3] Implement better factory access patterns for Random class MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace static readonly field with Lazy property for thread-safe lazy initialization - Add ThreadLocal property for thread-safe multi-threaded scenarios - Add factory methods Create() and Create(int seed) for explicit instance creation - Add CreateSecure() method for cryptographically secure random generation - Maintain full backwards compatibility with existing Default property access - Update comprehensive test coverage for all new factory methods Fixes #5 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- .../RandomHelpersTests.cs | 65 ++++++++++++++++++- csharp/Platform.Random/RandomHelpers.cs | 63 ++++++++++++++++-- 2 files changed, 122 insertions(+), 6 deletions(-) diff --git a/csharp/Platform.Random.Tests/RandomHelpersTests.cs b/csharp/Platform.Random.Tests/RandomHelpersTests.cs index 4f47704..c1411c9 100644 --- a/csharp/Platform.Random.Tests/RandomHelpersTests.cs +++ b/csharp/Platform.Random.Tests/RandomHelpersTests.cs @@ -1,13 +1,76 @@ using Xunit; +using System.Threading.Tasks; +using System.Threading; namespace Platform.Random.Tests { public class RandomHelpersTests { [Fact] - public void DefaultFieldTest() + public void DefaultPropertyTest() { Assert.NotNull(RandomHelpers.Default); + Assert.Same(RandomHelpers.Default, RandomHelpers.Default); + } + + [Fact] + public void ThreadLocalPropertyTest() + { + Assert.NotNull(RandomHelpers.ThreadLocal); + Assert.Same(RandomHelpers.ThreadLocal, RandomHelpers.ThreadLocal); + } + + [Fact] + public async Task ThreadLocalPropertyReturnsDifferentInstancesForDifferentThreadsTest() + { + System.Random mainThreadRandom = RandomHelpers.ThreadLocal; + System.Random? otherThreadRandom = null; + + var task = Task.Run(() => + { + otherThreadRandom = RandomHelpers.ThreadLocal; + }); + + await task; + + Assert.NotNull(mainThreadRandom); + Assert.NotNull(otherThreadRandom); + Assert.NotSame(mainThreadRandom, otherThreadRandom); + } + + [Fact] + public void CreateMethodTest() + { + var random1 = RandomHelpers.Create(); + var random2 = RandomHelpers.Create(); + + Assert.NotNull(random1); + Assert.NotNull(random2); + Assert.NotSame(random1, random2); + } + + [Fact] + public void CreateWithSeedMethodTest() + { + const int seed = 12345; + var random1 = RandomHelpers.Create(seed); + var random2 = RandomHelpers.Create(seed); + + Assert.NotNull(random1); + Assert.NotNull(random2); + Assert.NotSame(random1, random2); + + Assert.Equal(random1.Next(100), random2.Next(100)); + } + + [Fact] + public void CreateSecureMethodTest() + { + var secureRandom1 = RandomHelpers.CreateSecure(); + var secureRandom2 = RandomHelpers.CreateSecure(); + + Assert.NotNull(secureRandom1); + Assert.NotNull(secureRandom2); } } } diff --git a/csharp/Platform.Random/RandomHelpers.cs b/csharp/Platform.Random/RandomHelpers.cs index 93655b0..1d22613 100644 --- a/csharp/Platform.Random/RandomHelpers.cs +++ b/csharp/Platform.Random/RandomHelpers.cs @@ -1,15 +1,68 @@ +using System.Threading; + namespace Platform.Random { /// - /// Contains field-helper for class. - /// Содержит вспомогательное поле для класса . + /// Contains factory methods and properties for class. + /// Содержит фабричные методы и свойства для класса . /// public static class RandomHelpers { + private static readonly System.Lazy _default = new System.Lazy(() => new System.Random()); + + private static readonly ThreadLocal _threadLocal = new ThreadLocal(() => new System.Random()); + /// - /// Returns the pseudorandom number generator that is using the time of the first access to this field as seed. - /// Возвращает генератор псевдослучайных чисел использующий в качестве seed время первого обращения к этому полю. + /// Returns the pseudorandom number generator that is using the time of the first access to this property as seed. + /// Возвращает генератор псевдослучайных чисел использующий в качестве seed время первого обращения к этому свойству. /// - public static readonly System.Random Default = new System.Random(System.DateTime.UtcNow.Ticks.GetHashCode()); + public static System.Random Default => _default.Value; + + /// + /// Returns a thread-local pseudorandom number generator that provides thread-safe access. + /// Возвращает локальный для потока генератор псевдослучайных чисел, обеспечивающий потокобезопасный доступ. + /// + public static System.Random ThreadLocal => _threadLocal.Value!; + + /// + /// Creates a new pseudorandom number generator using system time as seed. + /// Создаёт новый генератор псевдослучайных чисел используя системное время в качестве seed. + /// + /// + /// A new instance of . + /// Новый экземпляр . + /// + public static System.Random Create() => new System.Random(); + + /// + /// Creates a new pseudorandom number generator using the specified seed value. + /// Создаёт новый генератор псевдослучайных чисел используя указанное значение seed. + /// + /// + /// A number used to calculate a starting value for the pseudo-random number sequence. + /// Число, используемое для вычисления начального значения последовательности псевдослучайных чисел. + /// + /// + /// A new instance of . + /// Новый экземпляр . + /// + public static System.Random Create(int seed) => new System.Random(seed); + + /// + /// Creates a cryptographically secure pseudorandom number generator. + /// Создаёт криптографически стойкий генератор псевдослучайных чисел. + /// + /// + /// A new instance of cryptographically secure random number generator. + /// Новый экземпляр криптографически стойкого генератора случайных чисел. + /// + public static System.Security.Cryptography.RandomNumberGenerator CreateSecure() + { +#if NET6_0_OR_GREATER + return System.Security.Cryptography.RandomNumberGenerator.Create(); +#else + return new System.Security.Cryptography.RNGCryptoServiceProvider(); +#endif + } } } From ba56a8cd2bd3a6a0f79d8b0c3c8099871cf69720 Mon Sep 17 00:00:00 2001 From: konard Date: Sun, 14 Sep 2025 13:36:47 +0300 Subject: [PATCH 3/3] 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 a2462db..0000000 --- a/CLAUDE.md +++ /dev/null @@ -1,5 +0,0 @@ -Issue to solve: https://github.com/linksplatform/Random/issues/5 -Your prepared branch: issue-5-5be42f02 -Your prepared working directory: /tmp/gh-issue-solver-1757845506800 - -Proceed. \ No newline at end of file