Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Random.Shared if available. #21089

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace System.Collections.Generic;

/// <summary>
/// <summary>
/// Extension methods for <see cref="IEnumerable{T}"/>.
/// </summary>
public static class AbpEnumerableExtensions
Expand Down Expand Up @@ -59,4 +59,24 @@ public static IEnumerable<T> WhereIf<T>(this IEnumerable<T> source, bool conditi
? source.Where(predicate)
: source;
}

/// <summary>
/// Shuffles the given <paramref name="source"/> using Fisher-Yates algorithm.
/// </summary>
/// <param name="source">The source to shuffle</param>
/// <param name="rng">Random number generator</param>
/// <returns>Shuffled enumerable</returns>
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source, Random rng)
{
var elements = source.ToArray();
for (var i = elements.Length - 1; i >= 0; i--)
{
// Swap element "i" with a random earlier element it (or itself)
// ... except we don't really need to swap it fully, as we can
// return it immediately, and afterwards it's irrelevant.
var swapIndex = rng.Next(i + 1);
yield return elements[swapIndex];
elements[swapIndex] = elements[i];
}
}
}
41 changes: 25 additions & 16 deletions framework/src/Volo.Abp.Core/Volo/Abp/RandomHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,41 +11,49 @@ namespace Volo.Abp;
/// </summary>
public static class RandomHelper
{
private static readonly Random Rnd = new Random();
private readonly static Random Rnd = new Random();

/// <summary>
/// Returns a random number within a specified range.
/// </summary>
/// <param name="minValue">The inclusive lower bound of the random number returned.</param>
/// <param name="maxValue">The exclusive upper bound of the random number returned. maxValue must be greater than or equal to minValue.</param>
/// <returns>
/// A 32-bit signed integer greater than or equal to minValue and less than maxValue;
/// that is, the range of return values includes minValue but not maxValue.
/// A 32-bit signed integer greater than or equal to minValue and less than maxValue;
/// that is, the range of return values includes minValue but not maxValue.
/// If minValue equals maxValue, minValue is returned.
/// </returns>
public static int GetRandom(int minValue, int maxValue)
{
#if NETSTANDARD2_0 || NETSTANDARD2_1
lock (Rnd)
{
return Rnd.Next(minValue, maxValue);
}
#else
return Random.Shared.Next(minValue, maxValue);
#endif
}

/// <summary>
/// Returns a nonnegative random number less than the specified maximum.
/// </summary>
/// <param name="maxValue">The exclusive upper bound of the random number to be generated. maxValue must be greater than or equal to zero.</param>
/// <returns>
/// A 32-bit signed integer greater than or equal to zero, and less than maxValue;
/// that is, the range of return values ordinarily includes zero but not maxValue.
/// A 32-bit signed integer greater than or equal to zero, and less than maxValue;
/// that is, the range of return values ordinarily includes zero but not maxValue.
/// However, if maxValue equals zero, maxValue is returned.
/// </returns>
public static int GetRandom(int maxValue)
{
#if NETSTANDARD2_0 || NETSTANDARD2_1
lock (Rnd)
{
return Rnd.Next(maxValue);
}
#else
return Random.Shared.Next(maxValue);
#endif
}

/// <summary>
Expand All @@ -54,10 +62,14 @@ public static int GetRandom(int maxValue)
/// <returns>A 32-bit signed integer greater than or equal to zero and less than <see cref="int.MaxValue"/>.</returns>
public static int GetRandom()
{
#if NETSTANDARD2_0 || NETSTANDARD2_1
lock (Rnd)
{
return Rnd.Next();
}
#else
return Random.Shared.Next();
#endif
}

/// <summary>
Expand Down Expand Up @@ -91,18 +103,15 @@ public static T GetRandomOfList<T>([NotNull] IList<T> list)
/// <param name="items">items</param>
public static List<T> GenerateRandomizedList<T>([NotNull] IEnumerable<T> items)
{
Check.NotNull(items, nameof(items));

var currentList = new List<T>(items);
var randomList = new List<T>();

while (currentList.Any())
var array = items.ToArray();
#if NETSTANDARD2_0 || NETSTANDARD2_1
lock (Rnd)
{
var randomIndex = RandomHelper.GetRandom(0, currentList.Count);
randomList.Add(currentList[randomIndex]);
currentList.RemoveAt(randomIndex);
return array.Shuffle(Rnd).ToList();
}

return randomList;
#else
Random.Shared.Shuffle(array);
return array.ToList();
#endif
}
}
Loading