zoukankan      html  css  js  c++  java
  • c# 扩展方法奇思妙用基础篇四:Random 扩展

    在 .Net 中,我们一般使用 Random 类来生成随机数,它仅提供了以下几个基本方法供我们使用:

    名称 说明
    公共方法 Next() 返回非负随机数。
    公共方法 Next(Int32) 返回一个小于所指定最大值的非负随机数。
    公共方法 Next(Int32, Int32) 返回一个指定范围内的随机数。
    公共方法 NextBytes 用随机数填充指定字节数组的元素。
    公共方法 NextDouble 返回一个介于 0.0 和 1.0 之间的随机数。

    如果想生成一些特殊的随机数,如枚举、日期等,则要再进行几步处理。本文将会扩展 Random 类,让随机更方便。

    Random 常用扩展

    布尔:NextBool

    随机返回 true 或 false,这个实现比较简单:

    public static bool NextBool(this Random random)
    {
        return random.NextDouble() > 0.5;
    }

    调用示例:

    bool b = random.NextBool();

    枚举: NextEnum

    public static T NextEnum<T>(this Random random)
        where T: struct
    {
        Type type = typeof(T);
        if (type.IsEnum == false) throw new InvalidOperationException();
    
        var array = Enum.GetValues(type);
        var index = random.Next(array.GetLowerBound(0), array.GetUpperBound(0) + 1);
        return (T)array.GetValue(index);
    }

    调用示例:

    enum Shape { Ellipse, Rectangle, Triangle }
    Shape shape = random.NextEnum<Shape>();

    NextBytes

    系统提供的 NextBytes 方法,要事先生成一个 byte 数组,不太方便。扩展一下,输入长度返回数组:

    public static byte[] NextBytes(this Random random, int length)
    {
        var data = new byte[length];
        random.NextBytes(data);
        return data;
    }

    调用示例:

    byte[] data = random.NextBytes(128);

    NextUInt16、NextInt16、NextFloat…

    有了 NextBytes 扩展,配合 BitConverter 类,我们可以扩展出很多:

    public static UInt16 NextUInt16(this Random random)
    {
        return BitConverter.ToUInt16(random.NextBytes(2), 0);
    }
    public static Int16 NextInt16(this Random random)
    {
        return BitConverter.ToInt16(random.NextBytes(2), 0);
    }
    public static float NextFloat(this Random random)
    {
        return BitConverter.ToSingle(random.NextBytes(4), 0);
    }

    时间日期:NextDateTime

    public static DateTime NextDateTime(this Random random, DateTime minValue, DateTime maxValue)
    {
        var ticks = minValue.Ticks + (long)((maxValue.Ticks - minValue.Ticks) * random.NextDouble());
        return new DateTime(ticks);
    }
    public static DateTime NextDateTime(this Random random)
    {
        return NextDateTime(random, DateTime.MinValue, DateTime.MaxValue);
    }

    调用示例:

    DateTime d = random.NextDateTime(new DateTime(2000, 1, 1), new DateTime(2010, 12, 31));

    Random 特定扩展

    开发中,面对的问题不同,可能需要不同的扩展,以下只提供几种扩展的思路,如需要,请自行实现:

    字符串

    1. 随机密码,可能需要正则表达式限制,如:
      var password = random.NextString(@"\d{6,8}");
      var passwordSalt = random.NextString(@"[0-9A-F]{16}");
    2. 随机国家、随机省、城市、地区名称,可能需要提供候选值,如:
      var country = random.NextCity("北京", "上海", "广州");
    3. 随机人名,一定不要生成乱码,要像名字,最好有百家姓和常用人名的数据。

    这几个实现起来有难度,有兴趣的朋友可以试下。

    验证码:

    1. 随机颜色(Color):RGB
    2. 随机字体(Font)
    3. 随机位置(Point)
    4. 随机旋转角度

    (本文中的代码仅供参考,如对随机有更专业的要求,可能不太适合。)

  • 相关阅读:
    LeetCode 24. Swap Nodes in Pairs (两两交换链表中的节点)
    LeetCode 1041. Robot Bounded In Circle (困于环中的机器人)
    LeetCode 1037. Valid Boomerang (有效的回旋镖)
    LeetCode 1108. Defanging an IP Address (IP 地址无效化)
    LeetCode 704. Binary Search (二分查找)
    LeetCode 744. Find Smallest Letter Greater Than Target (寻找比目标字母大的最小字母)
    LeetCode 852. Peak Index in a Mountain Array (山脉数组的峰顶索引)
    LeetCode 817. Linked List Components (链表组件)
    LeetCode 1019. Next Greater Node In Linked List (链表中的下一个更大节点)
    29. Divide Two Integers
  • 原文地址:https://www.cnblogs.com/ywsoftware/p/3128741.html
Copyright © 2011-2022 走看看