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
+ }
}
}