C#基础11-常用类
1、String
(1)基础特性
不可变性 C# 字符串(string
)是引用类型,但内容不可修改。 每次操作(如拼接、替换)都会创建新对象,旧对象由 GC 回收。频繁操作可能影响性能。 类似字符数组 可通过索引访问单个字符(如 str[0]
),但不能直接修改(如 str[0] = 'a'
会报错)。 需转换为 char[]
修改后再转回字符串:
char [ ] chars = str. ToCharArray ( ) ;
chars[ 1 ] = '为' ;
str = new string ( chars) ;
(2)常用操作
大小写转换:忽略用户输入大小写(如 Console.ReadLine().ToLower()
)
string lower = str. ToLower ( ) ;
string upper = str. ToUpper ( ) ;
string trimmed = str. Trim ( ) ;
string customTrim = str. Trim ( 'a' , 'b' ) ;
string [ ] words = str. Split ( new char [ ] { ' ' , ',' , '?' } , StringSplitOptions. RemoveEmptyEntries) ;
string joined = string . Join ( "-" , new string [ ] { "A" , "B" , "C" } ) ;
string sub1 = str. Substring ( 3 ) ;
string sub2 = str. Substring ( 3 , 2 ) ;
bool contains = str. Contains ( "abc" ) ;
int index = str. IndexOf ( "abc" ) ;
bool starts = str. StartsWith ( "He" ) ;
byte [ ] utf8Bytes = Encoding. UTF8. GetBytes ( str) ;
string fromGBK = Encoding. GetEncoding ( "GBK" ) . GetString ( bytes) ;
(3)性能优化
避免频繁拼接:循环内拼接字符串时,优先使用 StringBuilder
,效率比+=
提升数十倍
StringBuilder sb = new StringBuilder ( ) ;
for ( int i = 0 ; i < 1000 ; i++ ) { sb. Append ( "text" ) ;
}
string result = sb. ToString ( ) ;
高效字符串比较 :使用 StringComparison.Ordinal
或 OrdinalIgnoreCase
进行字节级比较,避免文化差异影响,性能提升显著:
bool equal = string . Equals ( str1, str2, StringComparison. OrdinalIgnoreCase) ;
(4)格式化输出
String.Format
与占位符:{index[,alignment][:formatString]}
string . Format ( "Name: {0,-10} Salary: {1,6:C}" , "Bill" , 123456 ) ;
- `index`:参数索引(从0开始)
- `alignment`:对齐方式(正数右对齐,负数左对齐)
- `formatString`:格式代码
string name = "Polly" ;
decimal salary = 7890.5m ;
Console. WriteLine ( $" { name, - 10 } { salary, 6 : C} " ) ;
标识符 说明 示例(输入123456.42) 输出 C
/c
货币格式 {0:C2}
¥123,456.42 D
/d
十进制整数 {0:D8}
00123456 F
/f
定点小数 {0:F3}
123456.420 N
/n
千位分隔数字 {0:N0}
123,456 P
/p
百分比 {0:P1}
(输入0.42)42.0% X
/x
十六进制 {0:X}
(输入255)FF E
/e
科学计数法 {0:E2}
1.23E+005
符号 作用 示例(输入1234.56) 输出 0
零占位符(补位) {0:000000.000}
001234.560 #
数字占位符(去空) {0:####.##}
1234.56 .
小数点 {0:0.000}
1234.560 ,
千位分隔符/缩放倍数 {0:0,.} {0:0,,}
1 (缩放千/百万倍) %
百分比转换 {0:0%}
(输入0.42)42% ;
分段格式化(正/负/零) {0:正数:#;负数:(#);零}
正数:1234
Console. WriteLine ( $" { 123456.42 : #,##0.00;(#,##0.00);zero} " ) ;
Console. WriteLine ( $" { - 123456.42 : #,##0.00;(#,##0.00);zero} " ) ;
区域性设置:使用 CultureInfo
适配本地化格式
double value = 1234.56 ;
string enUS = string . Format ( CultureInfo. GetCultureInfo ( "en-US" ) , "{0:C}" , value ) ;
string zhCN = string . Format ( CultureInfo. GetCultureInfo ( "zh-CN" ) , "{0:C}" , value ) ;
2、StringBuilder
(1)基础用法
StringBuilder sb = new StringBuilder ( "Hello" , 20 ) ;
Console. WriteLine ( $"Capacity: { sb. Capacity } " ) ;
sb. Append ( " World!" ) ;
- `AppendFormat()`:格式化追加
int price = 25 ;
sb. AppendFormat ( " Price: {0:C}" , price) ;
sb. Insert ( 6 , "C# " ) ;
- `Remove()`:删除子串
sb. Remove ( 5 , 4 ) ;
sb. Replace ( "World" , "Universe" ) ;
- `Clear()`:清空内容
sb. Clear ( ) ;
(2)性能优化
预分配容量 避免频繁扩容:初始化时预估最大长度(如日志拼接),减少内存复制开销。 避免链式操作 错误示例:sb.Append("A").Append("B").Append("C");
改进:单次Append()
合并内容:
sb. Append ( "A" ) . Append ( "B" ) ;
Unity游戏开发场景 在循环中拼接字符串时,StringBuilder
比String
减少90%的GC(垃圾回收)压力:
StringBuilder result = new StringBuilder ( ) ;
for ( int i = 0 ; i < 1000 ; i++ ) { result. Append ( i) ;
}
(3)与String的差异
特性 String
StringBuilder
可变性 不可变(修改生成新对象) 可变(原地修改字符数组) 内存开销 高(频繁修改时) 低(预分配缓冲池) 线程安全 是 ❌ 非线程安全(需手动同步) 适用场景 单次操作、常量字符串 循环拼接、动态构建大文本
(4)高级方法
char [ ] buffer = new char [ 10 ] ;
sb. CopyTo ( 0 , buffer, 0 , 5 ) ;
sb. EnsureCapacity ( 50 ) ;
if ( sb. Length == 0 ) { }
(5)实战示例
using System. Text ; StringBuilder log = new StringBuilder ( "Start: " , 100 ) ;
log. AppendLine ( "Operation 1 completed." ) . AppendFormat ( "Time: {0:HH:mm}" , DateTime. Now) ;
log. Replace ( "completed" , "SUCCESS" ) ;
Console. WriteLine ( log. ToString ( ) ) ;
输出: Start: Operation 1 SUCCESS. Time: 14:30
3、DateTime
(1)基础操作
DateTime now = DateTime. Now;
DateTime utcNow = DateTime. UtcNow;
DateTime today = DateTime. Today;
属性示例 now.Year
(年份)now.Month
(月份)now.Day
(日)now.Hour
(小时)now.Minute
(分钟)now.Second
(秒) 构造指定日期
DateTime customDate = new DateTime ( 2025 , 9 , 3 ) ;
DateTime withTime = new DateTime ( 2025 , 9 , 3 , 14 , 30 , 0 ) ;
(2)格式化输出
string shortDate = now. ToString ( "d" ) ;
string longDate = now. ToString ( "D" ) ;
string iso8601 = now. ToString ( "s" ) ;
string customFormat = now. ToString ( "yyyy-MM-dd HH:mm:ss" ) ;
string monthName = now. ToString ( "MMM" , new CultureInfo ( "en-US" ) ) ;
string dateOnly = now. ToShortDateString ( ) ;
string timeOnly = now. ToShortTimeString ( ) ;
️(3)比较与判断
int result = DateTime. Compare ( date1, date2) ;
bool isLater = date1 > date2;
bool isSameDay = date1. Date == date2. Date;
DayOfWeek day = now. DayOfWeek;
bool isLeapYear = DateTime. IsLeapYear ( now. Year) ;
(4)运算与时间差
DateTime tomorrow = now. AddDays ( 1 ) ;
DateTime lastMonth = now. AddMonths ( - 1 ) ;
DateTime nextHour = now. AddHours ( 1 ) ;
TimeSpan diff = date2 - date1;
Console. WriteLine ( $"相差: { diff. Days } 天, { diff. Hours } 小时" ) ;
精确单位:diff.TotalDays
(总天数)、diff.TotalMinutes
(总分钟数)
(5)实用场景
DateTime lastDay = new DateTime ( now. Year, now. Month, 1 ) . AddMonths ( 1 ) . AddDays ( - 1 ) ;
int lastDayNum = DateTime. DaysInMonth ( now. Year, now. Month) ;
int workingDays = 0 ;
for ( DateTime d = startDate; d <= endDate; d = d. AddDays ( 1 ) )
{ if ( d. DayOfWeek != DayOfWeek. Saturday && d. DayOfWeek != DayOfWeek. Sunday) workingDays++ ;
}
(6)注意事项
时区处理:涉及跨时区应用时,优先使用 DateTime.UtcNow
协调时间,避免本地时区混淆。 性能优化:频繁操作日期时(如循环计算),避免重复调用 DateTime.Now
(每次调用需系统交互),可缓存初始值。
4、TimeSpan
(1)创建实例
构造函数 :参数顺序(days, hours, minutes, seconds, milliseconds)
。
TimeSpan ts1 = new TimeSpan ( 10 , 30 , 0 ) ;
TimeSpan ts2 = new TimeSpan ( 2 , 14 , 18 , 35 ) ;
TimeSpan ts3 = new TimeSpan ( 0 , 0 , 0 , 0 , 500 ) ;
TimeSpan. FromDays ( 3.5 ) ;
TimeSpan. FromMinutes ( 90 ) ;
TimeSpan. FromMilliseconds ( 1500 ) ;
(2)算时间差
DateTime start = new DateTime ( 2025 , 1 , 1 , 8 , 0 , 0 ) ;
DateTime end = new DateTime ( 2025 , 1 , 1 , 17 , 30 , 45 ) ;
TimeSpan duration = end - start; Console. WriteLine ( duration) ;
结果可通过属性获取部分值(如 duration.Hours
返回 9)或总量(如 duration.TotalHours
返回 9.5125)。
(3)关键属性
属性 说明 示例值 (duration) Days
间隔的天数部分(不包含小时转换) 0 Hours
小时部分(0-23) 9 TotalHours
总小时数(含小数) 9.5125 TotalMinutes
总分钟数 570.75 Milliseconds
毫秒部分(0-999) 0 Ticks
100纳秒为单位的间隔(1秒=10^7) 342450000000
(4)格式转换
字符串转 TimeSpan: 支持格式:"6:15:30"
、"1.12:24:02"
(1天12小时)。
TimeSpan ts = TimeSpan. Parse ( "06:15:30" ) ;
bool success = TimeSpan. TryParse ( "6.15:30" , out ts) ;
ts. ToString ( @"dd\.hh\:mm\:ss" ) ;
$" { ts : %d} 天 { ts : %h} 小时" ;
(5)常见问题
精度问题:DateTime
最小单位是毫秒,TimeSpan
最小单位是 Tick(100纳秒),高精度计算需用 Ticks
。 负数间隔:若 start > end
,TimeSpan
属性值为负,可用 Duration()
取绝对值。
5、Stopwatch
(1)核心功能
Stopwatch stopwatch = new Stopwatch ( ) ;
stopwatch. Start ( ) ;
stopwatch. Stop ( ) ;
TimeSpan elapsed = stopwatch. Elapsed;
Console. WriteLine ( $"耗时: { elapsed. TotalMilliseconds } ms" ) ;
TimeSpan elapsed = Stopwatch. StartNew ( ( ) => {
} ) . Elapsed;
(2)注意事项
for ( int i = 0 ; i < 10 ; i++ ) { Stopwatch sw = new Stopwatch ( ) ; sw. Start ( ) ;
}
- 正确做法(复用静态实例):
static Stopwatch sw = new Stopwatch ( ) ;
for ( int i = 0 ; i < 10 ; i++ ) { sw. Restart ( ) ; sw. Stop ( ) ;
}
场景 方案 .NET 6+ 直接使用线程安全的 Stopwatch.StartNew()
旧版本.NET 为每个线程分配独立实例:new ThreadLocal<Random>(() => new Stopwatch())
精度与局限性 最高精度:依赖硬件支持,通常为 100纳秒级(通过 Stopwatch.IsHighResolution
检测)。 不适用场景:加密、安全相关操作(需改用 RNGCryptoServiceProvider
)。
(3)高级技巧
Stopwatch sw = Stopwatch. StartNew ( ) ;
MethodA ( ) ;
sw. Stop ( ) ;
TimeSpan timeA = sw. Elapsed; sw. Restart ( ) ;
MethodB ( ) ;
sw. Stop ( ) ;
TimeSpan timeB = sw. Elapsed;
var timings = new List< long > ( ) ;
for ( int i = 0 ; i < 100 ; i++ ) { sw. Restart ( ) ; sw. Stop ( ) ; timings. Add ( sw. ElapsedTicks) ;
}
double avgTicks = timings. Average ( ) ;
using ( SqlConnection conn = new SqlConnection ( connStr) ) { conn. Open ( ) ; Stopwatch sw = Stopwatch. StartNew ( ) ; var data = conn. Query ( "SELECT * FROM LargeTable" ) ; sw. Stop ( ) ; Log ( $"查询耗时: { sw. ElapsedMilliseconds } ms" ) ;
}
(4)场景优化
场景 推荐实践 短时操作测量 多次运行取平均值(避免单次误差) Web API响应监控 在中间件中集成Stopwatch,记录接口耗时 算法效率对比 结合GC.Collect()
和GC.WaitForPendingFinalizers()
排除GC干扰 高频调用代码分析 使用ElapsedTicks
替代毫秒计数(更高精度)
6、Math
(1)数学运算
取绝对值 Math.Abs(-5.3)
→ 5.3
(支持整数、浮点数) 幂与根号 幂运算:Math.Pow(2, 3)
→ 8
(计算2的3次方) 平方根:Math.Sqrt(9)
→ 3
指数与对数 自然指数:Math.Exp(2)
≈ 7.389
(e²) 常用对数:Math.Log10(100)
→ 2
(log₁₀100)
(2)取整与舍入
方法 说明 示例 结果 Math.Ceiling
向上取整 Math.Ceiling(2.1)
3
Math.Floor
向下取整 Math.Floor(2.9)
2
Math.Round
(默认)银行家算法(四舍六入五取偶) Math.Round(2.5)
2
Math.Round
(指定模式)强制四舍五入 Math.Round(2.5, MidpointRounding.AwayFromZero)
3
Math. Round ( Convert. ToDecimal ( 526.925 ) , 2 , MidpointRounding. AwayFromZero) ;
(3)三角函数
Math.Sin(Math.PI/6)
→ 0.5
(参数为弧度)Math.Atan2(y, x)
:计算点 (x,y)
的反正切角(自动处理象限)
double angle = Math. Atan2 ( 7 , 7 ) * 180 / Math. PI;
(4)高级工具库
功能:矩阵运算、线性代数、微积分等科学计算。 安装:
Install-Package MathNet.Numerics
using MathNet. Numerics. LinearAlgebra ;
var matrix = DenseMatrix. OfArray ( new double [ , ] { { 1 , 2 } , { 3 , 4 } } ) ;
var subMatrix = matrix. SubMatrix ( 0 , 2 , 0 , 1 ) ;
(5)关键常量
Math.PI
:圆周率π ≈ 3.14159
Math.E
:自然对数底e ≈ 2.71828
(6)最佳实践
精度问题:财务计算优先用 decimal
,避免 double
浮点误差。 矩阵运算:简单矩阵用原生数组,复杂计算(如求逆、特征值)用 Math.NET(效率提升10倍+)。
7、Random
(1)核心功能
Random rand = new Random ( ) ;
- 指定种子:相同种子生成相同随机序列(适用于测试)
Random fixedRand = new Random ( 123 ) ;
方法 作用 示例 Next()
生成0~2,147,483,647的整数 rand.Next()
→ 198273Next(int max)
生成0~max-1的整数 rand.Next(100)
→ 0~99Next(int min, int max)
生成min~max-1的整数 rand.Next(10, 20)
→ 10~19NextDouble()
生成0.0~1.0的双精度浮点数 rand.NextDouble()
→ 0.784NextBytes(byte[] buffer)
填充随机字节数组 byte[] buf = new byte[8]; rand.NextBytes(buf);
(2)注意事项
for ( int i = 0 ; i < 5 ; i++ )
{ Random r = new Random ( ) ; Console. WriteLine ( r. Next ( ) ) ;
}
- 正确做法:复用同一实例!
static Random rand = new Random ( ) ;
for ( int i = 0 ; i < 5 ; i++ )
{ Console. WriteLine ( rand. Next ( 100 ) ) ;
}
多线程安全方案 .NET 6+:使用线程安全的 Random.Shared
int num = Random. Shared. Next ( 1 , 100 ) ;
- 旧版本:为每个线程创建独立实例
private static readonly ThreadLocal< Random> threadRand = new ThreadLocal< Random> ( ( ) => new Random ( Guid. NewGuid ( ) . GetHashCode ( ) ) ) ;
随机性局限性 Random
生成的是伪随机数,不适合加密等高安全场景(需改用 RNGCryptoServiceProvider
)浮点数精度:NextDouble()
范围是 [0.0, 1.0)
,不含1.0
(3)进阶技巧
int num = rand. Next ( - 100 , 100 ) ;
double value = rand. NextDouble ( ) * 5.0 + 0.5 ;
string chars = "abcdefghijklmnopqrstuvwxyz0123456789" ;
string randomStr = new string ( Enumerable. Repeat ( chars, 8 ) . Select ( s => s[ rand. Next ( s. Length) ] ) . ToArray ( ) ) ;
(4)最佳实践
场景 推荐方案 原因 单线程应用 静态 Random
实例 避免重复种子问题 多线程应用 Random.Shared
(.NET 6+)或 ThreadLocal<Random>
线程安全且高效 加密/安全场景 System.Security.Cryptography.RandomNumberGenerator
真随机性要求 测试用例 固定种子的 Random
结果可复现
8、Guid
(1)核心功能
Guid guid = Guid. NewGuid ( ) ;
Console. WriteLine ( guid) ;
- 时间序生成(V7,.NET 9+)
Guid guidV7 = Guid. CreateVersion7 ( ) ;
Console. WriteLine ( guidV7) ;
格式符 输出示例 适用场景 D
(默认)9af7f46a-ea52-4aa3-b8c3-...
日志、显示 N
e0a953c3ee6040eaa9fae2b6...
紧凑存储(26字符) B
{734fd453-a4f8-4c5d-...}
序列化 X
{0x3fa412e3,0x8356,...}
底层调试
string guidStr = guid. ToString ( "N" ) ;
Guid parsedGuid = Guid. Parse ( "9af7f46a-ea52-4aa3-b8c3-9fd484c2af12" ) ;
if ( Guid. TryParse ( "invalid-guid" , out Guid safeGuid) ) { .. . }
- 字节数组转换
byte [ ] bytes = guid. ToByteArray ( ) ;
Guid fromBytes = new Guid ( bytes) ;
(2)注意事项
版本 特点 推荐场景 V4 完全随机,全局唯一 通用标识、临时令牌 V7 时间戳前缀,局部有序 数据库主键(减少索引碎片) V1/V2 含MAC地址,隐私风险 已弃用
for ( int i= 0 ; i< 1000 ; i++ )
{ var g = Guid. NewGuid ( ) ;
}
static readonly GuidGenerator = new Random ( ) ;
Guid[ ] guids = Enumerable. Repeat ( 0 , 1000 ) . Select ( _ => Guid. NewGuid ( ) ) . ToArray ( ) ;
存储优化 数据库字段 → 使用 uniqueidentifier
类型(SQL Server) 频繁传输 → 采用 N
格式字符串(26字符) 多线程安全 .NET 6+:无需额外处理,Guid.NewGuid()
内部线程安全 旧版本:通过 ThreadLocal
隔离实例
private static ThreadLocal< Random> _threadRand = new ThreadLocal< Random> ( ( ) => new Random ( Guid. NewGuid ( ) . GetHashCode ( ) ) ) ;
(3)高级技巧
public class Order
{ public Guid Id { get ; } = Guid. CreateVersion7 ( ) ; public string Product { get ; set ; }
}
string tempFile = $" { Guid. NewGuid ( ) : N} .tmp" ;
Directory. CreateDirectory ( $"uploads/ { Guid. NewGuid ( ) } " ) ;
using System. Security. Cryptography ;
byte [ ] cryptoBytes = new byte [ 16 ] ;
RandomNumberGenerator. Fill ( cryptoBytes) ;
Guid secureGuid = new Guid ( cryptoBytes) ;
(4)最佳实践
场景 推荐方案 原因 数据库主键 Guid.CreateVersion7()
(NET9+)时序性减少索引碎片 高频生成标识符 静态单例 Guid.NewGuid()
避免实例化开销 网络传输/存储 ToString("N")
节省空间(26字符 vs 36字符) 加密安全需求 RandomNumberGenerator
+ Guid
构造真随机性保障 历史代码兼容 Guid.Parse()
+ 格式校验防止无效输入导致崩溃
9、Stopwatch
(1)核心功能
Stopwatch stopwatch = new Stopwatch ( ) ;
stopwatch. Start ( ) ;
stopwatch. Stop ( ) ;
TimeSpan elapsed = stopwatch. Elapsed;
Console. WriteLine ( $"耗时: { elapsed. TotalMilliseconds } ms" ) ;
TimeSpan elapsed = Stopwatch. StartNew ( ( ) => {
} ) . Elapsed;
(2)注意事项
for ( int i = 0 ; i < 10 ; i++ ) { Stopwatch sw = new Stopwatch ( ) ; sw. Start ( ) ;
}
- 正确做法(复用静态实例):
static Stopwatch sw = new Stopwatch ( ) ;
for ( int i = 0 ; i < 10 ; i++ ) { sw. Restart ( ) ; sw. Stop ( ) ;
}
场景 方案 .NET 6+ 直接使用线程安全的 Stopwatch.StartNew()
旧版本.NET 为每个线程分配独立实例:new ThreadLocal<Random>(() => new Stopwatch())
精度与局限性 最高精度:依赖硬件支持,通常为 100纳秒级(通过 Stopwatch.IsHighResolution
检测)。 不适用场景:加密、安全相关操作(需改用 RNGCryptoServiceProvider
)。
(3)高级技巧
Stopwatch sw = Stopwatch. StartNew ( ) ;
MethodA ( ) ;
sw. Stop ( ) ;
TimeSpan timeA = sw. Elapsed; sw. Restart ( ) ;
MethodB ( ) ;
sw. Stop ( ) ;
TimeSpan timeB = sw. Elapsed;
var timings = new List< long > ( ) ;
for ( int i = 0 ; i < 100 ; i++ ) { sw. Restart ( ) ; sw. Stop ( ) ; timings. Add ( sw. ElapsedTicks) ;
}
double avgTicks = timings. Average ( ) ;
using ( SqlConnection conn = new SqlConnection ( connStr) ) { conn. Open ( ) ; Stopwatch sw = Stopwatch. StartNew ( ) ; var data = conn. Query ( "SELECT * FROM LargeTable" ) ; sw. Stop ( ) ; Log ( $"查询耗时: { sw. ElapsedMilliseconds } ms" ) ;
}
(4)场景优化
场景 推荐实践 短时操作测量 多次运行取平均值(避免单次误差) Web API响应监控 在中间件中集成Stopwatch,记录接口耗时 算法效率对比 结合GC.Collect()
和GC.WaitForPendingFinalizers()
排除GC干扰 高频调用代码分析 使用ElapsedTicks
替代毫秒计数(更高精度)