news 2026/5/10 9:23:33

C#核心技术四剑客:泛型、字典、文件IO与委托从入门到精通

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C#核心技术四剑客:泛型、字典、文件IO与委托从入门到精通

一、泛型(Generics)独立详解

1.泛型基础概念

// 为什么要用泛型? // 1. 类型安全 - 编译时检查 // 2. 代码重用 - 一套代码处理多种类型 // 3. 性能优化 - 避免装箱拆箱 // 泛型类定义 public class Repository<T> { private T _item; public T GetItem() => _item; public void SetItem(T item) => _item = item; } // 使用 Repository<int> intRepo = new Repository<int>(); Repository<string> stringRepo = new Repository<string>();

2.泛型方法

// 独立泛型方法 public T Max<T>(T a, T b) where T : IComparable<T> { return a.CompareTo(b) > 0 ? a : b; } // 方法类型推断(编译器自动推断T) int maxNum = Max(5, 10); // T推断为int string maxStr = Max("A", "B"); // T推断为string

3.泛型约束类型

// 主要约束类型 where T : class // 必须是引用类型 where T : struct // 必须是值类型(不包括可空类型) where T : new() // 必须有无参构造函数 where T : BaseClass // 必须继承自指定基类 where T : IInterface // 必须实现指定接口 where T : unmanaged // 必须是非托管类型(C# 7.3+) where T : notnull // 必须是非空类型(C# 8.0+) // 约束组合示例 public class Factory<T> where T : class, ICloneable, new() { public T Create() => new T(); }

4.泛型接口与继承

// 泛型接口 public interface IRepository<T> { void Add(T item); T Get(int id); } // 实现泛型接口 public class UserRepository : IRepository<User> { public void Add(User user) { /* 实现 */ } public User Get(int id) { /* 实现 */ } } // 泛型继承 public class BaseClass<T> { } public class DerivedClass<T> : BaseClass<T> { }

5.协变与逆变

// 协变 (out) - 允许返回更具体的类型 interface IProducer<out T> { T Produce(); } // 逆变 (in) - 允许接受更泛化的类型 interface IConsumer<in T> { void Consume(T item); } // 使用示例 IProducer<Dog> dogProducer = new DogProducer(); IProducer<Animal> animalProducer = dogProducer; // 协变,安全 IConsumer<Animal> animalConsumer = new AnimalConsumer(); IConsumer<Dog> dogConsumer = animalConsumer; // 逆变,安全

6.default关键字

// default值 T GetDefaultValue<T>() { return default(T); // 引用类型返回null,值类型返回0 } // C# 7.1+ 简写 T GetDefaultValue<T>() => default;

7.泛型与反射

// 运行时泛型类型操作 Type genericListType = typeof(List<>); Type stringListType = genericListType.MakeGenericType(typeof(string)); // 创建泛型实例 Type repoType = typeof(Repository<>); Type userRepoType = repoType.MakeGenericType(typeof(User)); object userRepo = Activator.CreateInstance(userRepoType);

8.泛型性能注意

// 避免值类型装箱 public class ValueContainer<T> where T : struct { // 直接存储值类型,无装箱开销 private T _value; } // 使用约束限制避免性能损失 public void Process<T>(T item) where T : struct { // 对于值类型,避免使用object转换 }

二、字典(Dictionary)重点回顾

1.核心特性

// 键值对集合 Dictionary<string, int> scores = new Dictionary<string, int>(); // 重要特性: // 1. 键必须唯一 // 2. 快速查找(近似O(1)) // 3. 无序集合(但遍历顺序是稳定的)

2.常用操作

// 添加和访问 scores.Add("Alice", 95); // 添加 scores["Bob"] = 87; // 添加或更新 // 安全访问 if (scores.TryGetValue("Alice", out int aliceScore)) { // 找到Alice的分数 } // 遍历 foreach (KeyValuePair<string, int> kvp in scores) { Console.WriteLine($"{kvp.Key}: {kvp.Value}"); } // 删除 scores.Remove("Alice"); // 删除指定键 scores.Clear(); // 清空所有

3.性能优化

// 1. 预设容量(减少扩容) var dict = new Dictionary<string, int>(1000); // 2. 自定义比较器 var caseInsensitiveDict = new Dictionary<string, int>( StringComparer.OrdinalIgnoreCase); // 3. 避免频繁的ContainsKey检查 // 不推荐: if (dict.ContainsKey(key)) { var value = dict[key]; } // 推荐: if (dict.TryGetValue(key, out var value)) { /* 使用value */ }

三、文件操作核心要点

1.常见读取方式

// 1. 一次性读取(小文件) string content = File.ReadAllText("file.txt"); // 2. 逐行读取(大文件) foreach (string line in File.ReadLines("file.txt")) { // 逐行处理 } // 3. 流式读取(完全控制) using (var reader = new StreamReader("file.txt")) { string line; while ((line = reader.ReadLine()) != null) { // 处理每一行 } } // 4. 异步读取 string content = await File.ReadAllTextAsync("file.txt");

2.重要注意事项

// 1. 总是使用using语句 // 错误:忘记释放资源 var reader = new StreamReader("file.txt"); // 正确:自动释放资源 using (var reader = new StreamReader("file.txt")) { // 处理文件 } // 2. 异常处理 try { string content = File.ReadAllText("file.txt"); } catch (FileNotFoundException ex) { Console.WriteLine($"文件不存在: {ex.Message}"); } catch (IOException ex) { Console.WriteLine($"IO错误: {ex.Message}"); } // 3. 路径处理 string fullPath = Path.Combine("folder", "subfolder", "file.txt"); string extension = Path.GetExtension(fullPath); string fileName = Path.GetFileNameWithoutExtension(fullPath);

四、委托(Delegate)核心机制

1.委托类型

// 1. 自定义委托(传统方式) delegate void MyDelegate(string message); // 2. 内置泛型委托(推荐) Action<string> actionDelegate; // 无返回值 Func<string, int> funcDelegate; // 有返回值 Predicate<string> predicateDelegate;// 返回bool // 3. 多播委托 Action multiDelegate = Method1; multiDelegate += Method2; // 添加方法 multiDelegate -= Method1; // 移除方法

2.Lambda表达式

// Lambda表达式简化委托 Func<int, int, int> add = (a, b) => a + b; Action<string> print = msg => Console.WriteLine(msg); // 带语句块的Lambda Func<int, int> factorial = n => { int result = 1; for (int i = 2; i <= n; i++) result *= i; return result; };

3.事件机制

// 标准事件模式 public class Publisher { // 1. 定义事件 public event EventHandler<MyEventArgs> MyEvent; // 2. 触发事件的方法 protected virtual void OnMyEvent(MyEventArgs e) { // 线程安全的调用 MyEvent?.Invoke(this, e); } } // 3. 事件参数类 public class MyEventArgs : EventArgs { public string Message { get; } public MyEventArgs(string message) => Message = message; }

五、四大技术的关联应用

1.泛型集合与文件操作

// 读取CSV文件到泛型列表 public List<T> ReadCsv<T>(string filePath, Func<string[], T> converter) { var result = new List<T>(); foreach (var line in File.ReadLines(filePath).Skip(1)) { var fields = line.Split(','); result.Add(converter(fields)); } return result; }

2.字典与委托结合

// 命令模式:字典存储命令处理器 var commandHandlers = new Dictionary<string, Action<string>>(); commandHandlers["save"] = data => SaveToFile(data); commandHandlers["load"] = data => LoadFromFile(data); // 执行命令 if (commandHandlers.TryGetValue(command, out var handler)) { handler(data); }

3.配置读取综合示例

public class ConfigLoader { // 泛型方法读取配置 public T GetConfig<T>(string key, T defaultValue = default) { // 从文件读取配置 var lines = File.ReadAllLines("config.txt"); var configDict = lines .Select(l => l.Split('=')) .Where(parts => parts.Length == 2) .ToDictionary(parts => parts[0], parts => parts[1]); // 尝试获取并转换 if (configDict.TryGetValue(key, out string value)) { return (T)Convert.ChangeType(value, typeof(T)); } return defaultValue; } }

六、最佳实践总结

技术使用场景注意事项
泛型1. 集合类
2. 通用算法
3. 工厂模式
1. 合理使用约束
2. 避免过度泛化
3. 注意类型推断
字典1. 快速查找
2. 缓存数据
3. 配置存储
1. 键的唯一性
2. 线程安全
3. 哈希碰撞
文件操作1. 配置读取
2. 数据持久化
3. 日志记录
1. 资源释放
2. 异常处理
3. 编码问题
委托1. 事件处理
2. 回调函数
3. LINQ查询
1. 内存泄漏
2. 线程安全
3. Lambda捕获

七、学习路径建议

  1. 初级阶段:掌握基本语法和使用场景

  2. 中级阶段:理解底层原理,能处理常见问题

  3. 高级阶段:熟练组合使用,进行性能优化

  4. 专家阶段:深入理解CLR实现,解决复杂问题

这四大技术是C#开发的基石,建议通过实际项目练习,逐步加深理解和应用能力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/7 19:20:18

阻塞队列:生产者-消费者模式

阻塞队列&#xff1a;生产者-消费者模式的优雅解决方案一、阻塞队列的诞生背景在多线程编程的世界里&#xff0c;生产者-消费者模式是最经典、最常见的并发模式之一。想象这样一个场景&#xff1a;一个线程负责生成数据&#xff08;生产者&#xff09;&#xff0c;另一个线程负…

作者头像 李华
网站建设 2026/5/9 17:08:24

AI播客震撼体验:量子物理对话竟由AI生成,声音真实到起鸡皮疙瘩

那个让我起鸡皮疙瘩的AI播客&#xff0c;彻底改变了我对声音的想象 昨天开车回家的路上&#xff0c;堵在三环动弹不得。百无聊赖中&#xff0c;我点开了一个朋友转给我的播客链接。节目里是一男一女两个主播&#xff0c;正在热火朝天地讨论一篇关于量子物理的论文。 男主播声…

作者头像 李华
网站建设 2026/5/3 1:20:10

深蓝词库转换:输入法词库互转的终极解决方案

深蓝词库转换&#xff1a;输入法词库互转的终极解决方案 【免费下载链接】imewlconverter ”深蓝词库转换“ 一款开源免费的输入法词库转换程序 项目地址: https://gitcode.com/gh_mirrors/im/imewlconverter 还在为不同输入法之间的词库不兼容而烦恼吗&#xff1f;深蓝…

作者头像 李华
网站建设 2026/5/2 14:21:39

如何快速掌握在线图表编辑器:新手完整入门指南

还在为技术文档的可视化表达而烦恼吗&#xff1f;在线图表制作工具已经成为现代工作必备的效率神器。通过文本驱动图表的方式&#xff0c;您可以轻松创建专业级可视化内容&#xff0c;而实时预览编辑功能让创作过程更加直观高效。 【免费下载链接】mermaid-live-editor Locatio…

作者头像 李华
网站建设 2026/5/4 17:07:27

百度网盘下载提速终极方案:第三方客户端实战指南

还在为百度网盘的龟速下载而抓狂&#xff1f;官方客户端的限速策略让无数用户头疼不已。今天&#xff0c;我将为你详细介绍基于BaiduPCS-Web的百度网盘第三方客户端解决方案&#xff0c;帮助你突破速度限制&#xff0c;享受极速下载体验。 【免费下载链接】baidupcs-web 项目…

作者头像 李华
网站建设 2026/5/9 21:57:10

Python多线程实战:12306抢票系统的并发处理优化

一、引言&#xff1a;为什么12306抢票需要多线程&#xff1f; 在12306抢票系统中&#xff0c;并发处理是提升抢票成功率的关键因素之一。抢票过程涉及多个耗时操作&#xff1a; CDN筛选&#xff1a;需要测试大量CDN节点的响应速度用户状态检查&#xff1a;需要定期验证登录状态…

作者头像 李华