解读 ABP RandomHelper 内部实现源码
ABP 源码中存在一个对随机值 Random 的封装帮助类,可以帮助用户快速获取随机数,并且该类是以单例模式封装,还可以提升复用率以及性能。下面我们来解读下 RandomHelper 类的具体实现。
1.首先声明静态只读 Random (单例)
private static readonly Random Rnd = new Random();
2.通过传入最小最大值取随机整数,不得不佩服大佬的写作能力,就这么一行代码竟然可以写出 6 行注释,注释翻译出来放在代码后面
/// <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.
/// If minValue equals maxValue, minValue is returned.
/// </returns>
public static int GetRandom(int minValue, int maxValue)
{
lock (Rnd)
{
return Rnd.Next(minValue, maxValue);
}
}
注释大意:返回指定范围内的随机数。
一个32位带符号整数,大于或等于minValue,小于maxValue;
也就是说,返回值的范围包括minValue而不是maxValue。
如果minValue等于maxValue,则返回minValue。
3.通过传入最大值获取随机整数
/// <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.
/// However, if maxValue equals zero, maxValue is returned.
/// </returns>
public static int GetRandom(int maxValue)
{
lock (Rnd)
{
return Rnd.Next(maxValue);
}
}
注释大意:返回一个小于指定最大值的非负随机数。
要生成的随机数的唯一上界。maxValue必须大于或等于0
一个大于或等于零且小于maxValue的32位带符号整数;
也就是说,返回值的范围通常包括0,但不包括maxValue。
但是,如果maxValue等于0,则返回maxValue。
4.获取整数类型0与int.max 之间的整数
/// <summary>
/// Returns a nonnegative random number.
/// </summary>
/// <returns>A 32-bit signed integer greater than or equal to zero and less than <see cref="int.MaxValue"/>.</returns>
public static int GetRandom()
{
lock (Rnd)
{
return Rnd.Next();
}
}
5.获取集合中随机的对象
/// <summary>
/// Gets random of given objects.
/// </summary>
/// <typeparam name="T">Type of the objects</typeparam>
/// <param name="objs">List of object to select a random one</param>
public static T GetRandomOf<T>(params T[] objs)
{
if (objs.IsNullOrEmpty())
{
throw new ArgumentException("objs can not be null or empty!", "objs");
}
return objs[GetRandom(0, objs.Length)];
}
示例:
RandomHelper.GetRandomOf("A", "B", "C", "D")
6.从指定枚举集合中生成一个随机列表
/// <summary>
/// Generates a randomized list from given enumerable.
/// </summary>
/// <typeparam name="T">Type of items in the list</typeparam>
/// <param name="items">items</param>
public static List<T> GenerateRandomizedList<T>(IEnumerable<T> items)
{
var currentList = new List<T>(items);
var randomList = new List<T>();
while (currentList.Any())
{
var randomIndex = RandomHelper.GetRandom(0, currentList.Count);
randomList.Add(currentList[randomIndex]);
currentList.RemoveAt(randomIndex);
}
return randomList;
}
至此这个 ABP 中封装的 RandomHelper 类就讲解完了,各位根据实际场景选用。对于绝大部分场景来说,其实用和不用区别可能不大,个人选择使用主要是为了与源码靠近。大家也看到了,整个类中就 5 个方法,到是有一点 RandomHelper 类中加了锁的。