解读 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 类中加了锁的。

posted @ 2019-06-26 15:09  Jöhan  阅读(147)  评论(0编辑  收藏  举报