C# 中 Random 类分析
Random 类用于生成伪随机数,位于 System 命名空间。它的核心机制是基于一个种子值 (seed),通过算法生成看似随机的数列。相同种子会生成相同的随机数序列,这在需要可重现的随机场景中很有用。
核心特点
-
种子与随机性
-
默认构造函数使用当前时间戳作为种子,因此每次运行生成不同序列。
-
若显式指定种子(如
new Random(123)),则生成确定性序列。
Random rnd1 = new Random(1); Random rnd2 = new Random(1); Console.WriteLine(rnd1.Next() == rnd2.Next()); // 输出 True -
-
线程安全
-
Random实例非线程安全,多线程环境需外部同步(如锁)。 -
推荐每个线程使用独立的
Random实例,或使用线程安全的System.Random.Shared(.NET 6+)。
-
-
生成范围
-
Next():生成 0 到int.MaxValue之间的整数。 -
Next(int max):生成 0 到max-1之间的整数。 -
Next(int min, int max):生成[min, max)区间的整数(含 min,不含 max)。
-
-
浮点数生成
NextDouble():生成 0.0 到 1.0 之间的双精度浮点数(不含 1.0)。
常见问题与优化
-
问题 :短时间内创建多个
Random实例可能生成相同序列(因时间种子相同)。// 错误示例:短时间内创建多个实例 for (int i = 0; i < 3; i++) { Console.WriteLine(new Random().Next(100)); // 可能输出相同值 } -
解决方案 :复用单个
Random实例。Random rnd = new Random(); for (int i = 0; i < 3; i++) { Console.WriteLine(rnd.Next(100)); // 正确输出不同随机数 } -
高级需求 :若需更高质量的随机数(如密码学场景),使用
System.Security.Cryptography.RandomNumberGenerator。
C# 中 DateTime 类分析
DateTime 表示特定的时间点,精度为 100 纳秒,存储为自 0001 年 1 月 1 日以来的 ticks 数 。它是值类型 (struct),不可变。
核心特点
-
三种类型
-
DateTimeKind.Utc:协调世界时(如DateTime.UtcNow)。 -
DateTimeKind.Local:本地时间(如DateTime.Now)。 -
DateTimeKind.Unspecified:未指定时区的时间(默认)。
-
-
常用属性
DateTime now = DateTime.Now; Console.WriteLine(now.Year); // 年 Console.WriteLine(now.Month); // 月 Console.WriteLine(now.DayOfWeek); // 星期几(枚举) -
日期运算
- 使用
AddDays(),AddHours(),AddMonths()等方法返回新的DateTime。
DateTime tomorrow = DateTime.Now.AddDays(1); - 使用
-
比较与差值
DateTime a = DateTime.Now; DateTime b = a.AddHours(1); TimeSpan diff = b - a; Console.WriteLine(diff.TotalHours); // 输出 1
时区处理
-
本地时间与 UTC:
DateTime local = DateTime.Now; DateTime utc = local.ToUniversalTime(); // 转换为 UTC -
时区转换
:需使用TimeZoneInfo类(.NET 3.5+)。
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("China Standard Time"); DateTime chinaTime = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, tz);
字符串与 DateTime 互转
-
解析字符串:
DateTime.Parse("2023-10-01"); // 自动解析 DateTime.ParseExact("20231001", "yyyyMMdd", null); // 指定格式 -
格式化输出:
DateTime now = DateTime.Now; Console.WriteLine(now.ToString("yyyy-MM-dd")); // 输出:2023-10-01 Console.WriteLine(now.ToString("HH:mm:ss")); // 输出:14:30:00
C# 中 String 类分析
String 是引用类型,但具有不可变性 (immutable),所有操作都会返回新字符串。它本质是 char 数组的封装。
核心特点
-
不可变性
string s = "hello"; s.ToUpper(); // 返回新字符串 "HELLO",原 s 不变 -
字符串池(String Intern Pool)
-
相同字面量的字符串共享内存:
string a = "test"; string b = "test"; Console.WriteLine(object.ReferenceEquals(a, b)); // 输出 True -
通过
string.Intern()手动入池:
string c = string.Intern(new StringBuilder("test").ToString()); Console.WriteLine(object.ReferenceEquals(a, c)); // 输出 True
-
-
常用操作
string s = " Hello, World! "; Console.WriteLine(s.Trim()); // 去除空格 Console.WriteLine(s.Contains("World")); // 检查包含 Console.WriteLine(s.Substring(7, 5)); // 截取 "World"
性能优化
-
频繁拼接 :使用
StringBuilder避免创建过多临时字符串。StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1000; i++) { sb.Append(i); } string result = sb.ToString(); // 高效拼接 -
字符串插值 :比
string.Format更简洁高效。string name = "Alice"; string msg = $"Hello, {name}!"; // 等价于 string.Format("Hello, {0}!", name)
内存注意事项
-
大字符串的
Substring()可能导致内存泄漏(.NET Framework 中),.NET Core 已修复。 -
推荐使用
Span<char>或Memory<char>处理大字符串切片,避免内存复制。
三者对比总结
| 类 | 类型 | 核心特性 |
|---|---|---|
Random |
引用类型 | 伪随机数生成器,需注意种子和线程安全问题。 |
DateTime |
值类型 | 不可变,存储为 ticks,支持时区转换和格式化。 |
String |
引用类型 | 不可变,支持丰富操作,注意性能优化(如 StringBuilder 和插值)。 |