当前位置: 首页 > news >正文

常见类后续,泛型,文件

引言

常见类后续较为重要的大体可以概述为“集合List","字典Dictionary",二者均为容器对象(存储多个元素),二者异中有同

  • List集合: 可变长度(扩容), 提供丰富方法, 元素可重复

  • 字典: 可变长度(扩容),提供丰富方法, key-value(键值对), key唯一, value可重复

泛型:通过泛型,你可以创建适用于多种数据类型的类、接口、委托和方法,而无需为每种类型编写重复代码。

文件:内存中存放的数据在计算机关机后就会消失。要长久保存数据,就要使用硬盘、光盘、U 盘等设备。为了便于数据的管理和检索,引入了“文件”的概念。

常见类后续

1.集合List

ArrayList: 早期的List集合, 不支持泛型, object[], 添加任意类型的元素, 向上转型为object(装箱操作), 获取元素(object), 手动向下转型(拆箱操作), 效率低, 无安全检查。

List<T>: 泛型List集合,<T>: 定义一个T数据类型变量, 创建List集合对象,给T赋值:List<int>限制集合存储元素类型, 避免装箱拆箱操作。

///注意点:装箱:添加任意类型的元素, 向上转型为object;拆箱:获取元素(object), 手动向下转型

1.Arraylist

ArrayList是 C# 中一个经典的集合类型,位于System.Collections命名空间中。它是 .NET Framework 早期版本中的动态数组实现,可以存储任意类型的对象。可以将ArrayList类看作扩充了功能的数组,但它并不等同于数组。使用ArrayList类要添加引用:using.System.Collections;

特点:

动态数组:底层使用数组实现,自动处理扩容非泛型集合:存储 System.Object 类型的元素

索引访问:支持类似数组的索引器访问允许重复:同一元素可以多次添加

2.List<T>泛型集合

List<T>是 C# 中最常用的集合类型之一,它属于System.Collections.Generic命名空间,提供了强大的动态数组功能。使用ArrayList存储的数据都是object类型,操作的时候经常要进行类型转换,效率低并且类型转换时容易出错,可以使用泛型集合来改进。泛型集合可以约束集合内的元素类型

对比:

名称ArrayListList<T>
类型安全非泛型,存储 object 类型泛型,编译时类型检查
性能需要装箱/拆箱操作,性能较低需装箱/拆箱,性能更高
线程安全非线程安全非线程安全

方法:

遍历:foreach 循环,若循环操作中,涉及到增删改等操作,会在运行时抛出异常,而for i循环中则无此情况,推荐使用for i循环

排序 Sort():进行排序, 要求提供比较强

ICompareable比较器:要求元素所在类实现接口, 默认排序, 在A业务中,需要的ICompareable指定的排序规则, 在B业务中, 不需要的ICompareable指定的排序规则, 另外排序规则, 不能直接修改类的CompareTo()方法。

IComparer接口: 不需要在元素所在类实现接口, 只需要编写类实现这个接口的int Compare(object x, object y);如果某个类比较规则很多, 编写很多个实现IComparer接口类,造成类暴增, 比较规则只使用一次。

Comparison委托: 只需要提供方法, 结合lambda表达式, 在使用的时候,创建方法,优化: 不需要创建类,只需要在调用Sort()方法时.使用代码动态去创建一个比较规则 Comparison(委托)

List<int> list = new List<int>() { 2,5,3,10,8,7 } ///使用委托进行比较 list.Sort((num1,num2)=> num1-num2);

寻找元素:

FindIndex:返回第一个匹配元素的下标

int firstEven = numbers.Find(x => x % 2 == 0); // 返回 2

Find:返回匹配的第一个元素

int index = numbers.FindIndex(x => x > 3); // 返回 3

FindAll:返回满足条件的所有元素

int index = numbers.FindIndex(x => x > 3); // 返回 3

2.字典

key唯一, value可重复, key不能是null ,这一种一一对应关系称为字典, key--> value关系 存储一对key,value 使用字典。

C#有两种: 非泛型字典: HashTable 泛型字典: Dictionary<T>

1.HashTable

Hashtable通常称为哈希表,它表示键/值对的集合,这些键/值对根据键的哈希代码进行组织。它的每个元素都是一个存储在DictionaryEntry对象中的键/值对。键不能为空引用,但值可以。

hash算法:根据key进行hash算法,得到对应hash值, 根据hash值找Bucket数组的位置(下标) 下标 = hash % 桶的长度; 11 31%11 = 9 9%11 = 9

Hash冲突: 1. key不一样,但是计算得到hash码一样 1. key不一样, hash值不一样, 计算得到桶的下标一样。

解决方法:可以使用开放寻址法处理冲突

方法:遍历

1. 第一种方式先得到key的集合(Keys), 遍历key集合, 通过key获取value

foreach (object key in hashtable.Keys) { //通过key获取value 通过索引器 object value = hashtable[key]; Console.WriteLine($"key:{key}-->value:{value}"); }

2.第二种方式: 遍历HashTable集合, 得到DictionaryEntry(包含key,value)

foreach (DictionaryEntry entry in hashtable) { Console.WriteLine($"{entry.Key}:{entry.Value}"); }

|

方法作用
void Remove(object key)根据指定的 key 值移除对应的集合元素。
void Clear()清空集合。
ContainsValue(object value)判断集合中是否包含指定 value 值的元素

2.Dictionary字典

实际开发中, 推荐使用Dictionary<K,V>, 它的方法与HashTable一样, 底层数据结构不一样, HashTable底层是Bucket对象数组, Dictionary底层是数组+链表(哈希表)。

方法同上

拓展方法:

  • ToList() 把字典转换为List, 元素KeyValuePair

  • 排序好的集合 OrderBy(Func委托) 升序排序

static void Main(string[] args) { Dictionary<string,int> dict = new Dictionary<string, int> { { "one", 1 }, { "two", 5 }, { "three", 3 } // 等价于上面写法 //["one"] = 1, //["two"] = 2, //["three"] = 3 }; //ToList() 把字典转换为列表, Dictionary: key-value键值对封装成: KeyValuePair<TKey,TValue> //List<KeyValuePair<string, int>> list = dict.ToList(); //// 按照值排序 Sort() //list.Sort((a,b)=>b.Value - a.Value); //list.ForEach((kvp)=> Console.WriteLine($"{kvp.Key}:{kvp.Value}")); //排序方法 OrderBy() 升序排序 OrderByDescending() 降序排序 //根据哪一个字段(表达式)排序 //var orderDict = dict.OrderBy(kvp=>kvp.Value); var orderDict = dict.OrderByDescending(kvp => kvp.Value); Console.WriteLine(string.Join("\n",orderDict)); Dictionary<string,Student> studentDict = new Dictionary<string, Student> { { "1", new Student{ Id=1,Name="张三",Age=18 } }, { "2", new Student{ Id=2,Name="李四",Age=20 } }, { "3", new Student{ Id=3,Name="王五",Age=19 } } }; //根据学生的年龄进行排序 var orderStuDict = studentDict.OrderByDescending(kvp => kvp.Value.Age); Console.WriteLine(string.Join("\n", orderStuDict)); } }

泛型

数据类型参数化,通过泛型,你可以创建适用于多种数据类型的类、接口、委托和方法,而无需为每种类型编写重复代码。其泛型变量本质就是一个站位符;

1:使用场景:

1:泛型变量定义方式

  • 泛型类: 在类声明后面定义泛型变量, 这泛型变量的作用域在整个类都有效

/// <summary> /// 泛型类 /// </summary> internal class Demo2<T> { //字段使用 private T data; //属性使用 public T Data { get { return data; } set { data = value; } } //构造方法使用 public Demo2(T data) { this.data = data; } public Demo2() { } //非静态方法使用 public T Fun(T t) { return t; } //静态方法使用 public static void Fun2(T t) { } }
  • 泛型方法: 在方法定义后面定义泛型变量, 作业域: 只在该方法内使用

2:泛型变量赋值

申明在方法上的泛型变量, 调用这个方法的时候赋值, 可以不需要使用<数据类型>显示赋值, 如果泛型变量在参数上使用, 给参数传递什么类型的值, 泛型变量数据类型就是该参数对应数据类型(隐式赋值);

//注意点 如果泛型变量作为参数使用: 可以显示赋值, 也可以隐式赋值, 推荐隐式赋值如果泛型变量只作为返回值类型使用, 只能显示赋值

2:泛型约束

限制泛型变量赋值范围,如果泛型没有约束, 值可以是任意数据类型

约束说明
where T : structT必须是值类型(包括枚举,非null)
where T : classT必须是引用类型(包括null)
where T : new()T必须有无参构造函数
where T : 基类名T必须继承自指定基类
where T : 接口名T必须实现指定接口
where T : UT必须与U相同或是U的派生类(U也是类型参数)

///注意点:泛型约束必须写在类,方法定义最后

文件

想看的话,关注笔者,下周在更新。

http://www.jsqmd.com/news/88469/

相关文章:

  • 蓝桥杯Python-语法基础-2
  • WAN2.2-14B-Rapid-AllInOne实战指南:从零到精通的完整视频生成方案
  • JSP如何整合第三方控件支持大文件上传?
  • OrcaSlicer依赖库实战构建指南:从源码到高性能G代码生成器
  • 8088单板机 NASM汇编实验方法与步骤
  • C++树形数据结构————树状数组、线段树中“逆序对”的问题
  • Flutter工程化实战:从单人开发到团队协作的规范与效率指南
  • yaml-cpp内存优化策略深度解析:从性能瓶颈到高效解决方案
  • Windows11系统文件verifier.dll丢失或损坏问题 下载修复
  • 软件打开出现找不到Vfp6rchs.dll文件 丢失的情况 下载修复
  • 会员管理系统如何成为企业数字化转型的增长核心
  • Comtos Linux 追求的哲学
  • Qwen-Rapid-AIO模型加载异常全面排障:从现象到根治的完整指南
  • Flutter性能优化实战:从卡顿排查到极致体验的落地指南
  • 毕业设计项目 基于机器视觉的目标跟踪算法
  • AI视频创作三步合规法:从风险规避到版权保护实战指南
  • 用了3个月PandaWiki,我终于和知识管理和解了|超省心使用心得
  • 入门C语言学习---从零开始
  • 中高端路由器选购指南:Wi-Fi 7与硬件配置全解析
  • mustache.js实战精通:从入门到高级应用的完整指南
  • Nginx核心架构设计
  • 2025最新数码前置仓/数码外卖仓/数码外卖店品牌合作首选——六米生活,轻创业优选/美团闪购/淘宝闪购/即时零售/小时达加盟领航者值得信赖 - 全局中转站
  • 【Git原理与使用】(五)Git 多人协作:从分支协作到冲突解决,团队开发效率翻倍秘籍
  • 2025年年终全自动洗车机厂家推荐:专家严选,不同运营场景下的5款高可靠性品牌清单 - 品牌推荐
  • Ansible-Playbook
  • 【Git原理与使用】(六)Git 企业级开发模型实战:从分支规范到 DevOps 全流程落地
  • 教程 32 - 几何体系统
  • ChanlunX缠论插件:让技术分析变得简单直观的智能助手
  • 【学习记录】第六周
  • 2025 年全国小学生统一考试 数学