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 和插值)。 |