C# 集合与泛型
文章目录
- 前言
- 1.什么是集合?
- 2.非泛型集合(了解即可)
- 2.1常见的非泛型集合
- 3.泛型的概念
- 4.常用的泛型集合
- 5. 自定义泛型类和方法
- 5.1 自定义泛型类
- 5.2 自定义泛型方法
前言
C# 中,集合(Collection)是一组有序的数据结构,用于存储和管理一组对象。泛型(Generics)则是 .NET Framework 中一个强大且灵活的功能,它允许我们创建类型安全且高效的集合。本篇文章将详细介绍 C# 中的集合类型、泛型的使用以及如何结合两者高效管理数据。
1.什么是集合?
集合是一组可以存储、管理多个数据的对象容器。集合与数组类似,但集合的容量可以动态调整,不必在声明时指定长度。C# 中的集合分为两种类型:
- 非泛型集合:如 ArrayList、Hashtable,可以存储不同类型的数据,但缺乏类型安全性,需进行频繁的类型转换。
- 泛型集合:如 List、Dictionary<TKey, TValue>,只能存储指定类型的数据,提供了更好的性能和类型安全性。
2.非泛型集合(了解即可)
早期的集合类位于 System.Collections 命名空间中,包括 ArrayList、Hashtable 等。非泛型集合由于可以存储不同类型的数据,灵活性较强,但在存储和取出数据时需进行类型转换,且缺乏编译时类型检查,容易出现类型不匹配的错误。
2.1常见的非泛型集合
- ArrayList:类似数组,但大小可动态调整,存储任何类型的数据。
- Hashtable:键值对的集合,键和值均可为任意类型。
示例:使用 ArrayList 和 Hashtable
using System;
using System.Collections;class NonGenericCollections
{static void Main(){// ArrayList 示例ArrayList arrayList = new ArrayList();arrayList.Add(1);arrayList.Add("Hello");arrayList.Add(3.14);foreach (var item in arrayList){Console.WriteLine(item); // 输出:1, Hello, 3.14}// Hashtable 示例Hashtable hashtable = new Hashtable();hashtable["name"] = "Alice";hashtable["age"] = 25;foreach (DictionaryEntry entry in hashtable){Console.WriteLine($"{entry.Key}: {entry.Value}");}}
}
3.泛型的概念
泛型(Generics)允许我们在创建类、接口或方法时定义一个或多个类型参数(通常用 表示),并在使用时指定具体的类型。这种机制在运行时提供类型安全检查,避免了频繁的类型转换。
泛型的优点
- 类型安全:在编译时检查类型一致性,避免类型错误。
- 性能提升:减少装箱(boxing)和拆箱(unboxing),提高效率。
- 可读性和可维护性:代码更清晰、直观,不需要强制类型转换。
4.常用的泛型集合
C# 中常用的泛型集合类位于 System.Collections.Generic 命名空间中。以下是一些常用的泛型集合类:
4.1 List < T > <T> <T>
L i s t < T > List<T> List<T> 是一种动态数组,可根据需要动态调整大小。List 提供了便捷的方法来操作列表中的元素,如添加、删除、排序、搜索等。
using System;
using System.Collections.Generic;class ListExample
{static void Main(){List<int> numbers = new List<int> { 1, 2, 3 };numbers.Add(4);numbers.Remove(2);foreach (int number in numbers){Console.WriteLine(number); // 输出:1, 3, 4}// 检查列表中是否包含某个元素bool containsThree = numbers.Contains(3); // trueConsole.WriteLine("包含3吗?" + containsThree);}
}
4.2 Dictionary<TKey, TValue>
Dictionary<TKey, TValue> 是一种键值对集合,允许通过键快速访问对应的值。键在字典中是唯一的,但值可以重复。
using System;
using System.Collections.Generic;class DictionaryExample
{static void Main(){Dictionary<string, int> ages = new Dictionary<string, int>{{ "Alice", 25 },{ "Bob", 30 }};ages["Charlie"] = 35;foreach (var pair in ages){Console.WriteLine($"{pair.Key}: {pair.Value}");}// 检查是否存在特定键if (ages.ContainsKey("Alice")){Console.WriteLine("Alice的年龄是: " + ages["Alice"]);}}
}
4.3 Queue < T > <T> <T>
Q u e u e < T > Queue<T> Queue<T> 是一个先进先出(FIFO)的集合。适合用在需要按顺序处理任务的场景,例如任务队列。
using System;
using System.Collections.Generic;class QueueExample
{static void Main(){Queue<string> queue = new Queue<string>();queue.Enqueue("Task1");queue.Enqueue("Task2");while (queue.Count > 0){string task = queue.Dequeue();Console.WriteLine("处理: " + task);}}
}
4.4 S t a c k < T > Stack<T> Stack<T>
S t a c k < T > Stack<T> Stack<T> 是一个后进先出(LIFO)的集合。适合用于临时存储数据或实现特定算法(如递归)。
using System;
using System.Collections.Generic;class StackExample
{static void Main(){Stack<string> stack = new Stack<string>();stack.Push("Page1");stack.Push("Page2");while (stack.Count > 0){string page = stack.Pop();Console.WriteLine("返回: " + page);}}
}
4.5 H a s h S e t < T > HashSet<T> HashSet<T>
H a s h S e t < T > HashSet<T> HashSet<T> 是一个无序集合,用于存储唯一值。适合用于需要唯一元素的场景,如不重复数据的集合。
using System;
using System.Collections.Generic;class HashSetExample
{static void Main(){HashSet<int> set = new HashSet<int> { 1, 2, 3 };set.Add(3); // 重复添加将被忽略set.Add(4);foreach (int item in set){Console.WriteLine(item); // 输出:1, 2, 3, 4}}
}
5. 自定义泛型类和方法
5.1 自定义泛型类
可以创建自己的泛型类,使其在不同的数据类型上复用。以下是一个简单的泛型栈实现:
using System;class GenericStack<T>
{private T[] elements;private int index = 0;public GenericStack(int size){elements = new T[size];}public void Push(T item){elements[index++] = item;}public T Pop(){return elements[--index];}
}class Program
{static void Main(){GenericStack<int> stack = new GenericStack<int>(5);stack.Push(1);stack.Push(2);Console.WriteLine(stack.Pop()); // 输出:2}
}
5.2 自定义泛型方法
泛型方法允许在方法中定义类型参数,使用方式和泛型类类似。以下是一个交换两个变量值的泛型方法示例:
using System;class Program
{static void Swap<T>(ref T a, ref T b){T temp = a;a = b;b = temp;}static void Main(){int x = 10, y = 20;Swap(ref x, ref y);Console.WriteLine($"x = {x}, y = {y}"); // 输出:x = 20, y = 10}
}
相关文章:
C# 集合与泛型
文章目录 前言1.什么是集合?2.非泛型集合(了解即可)2.1常见的非泛型集合 3.泛型的概念4.常用的泛型集合4.1 List < T > <T> <T>4.2 Dictionary<TKey, TValue>4.3 Queue < T > <T> <T>4.4 S t a c…...
el-date-picker 设置开始时间和结束时间
<el-date-picker v-model"ruleForm.RECORDDATE" type"date" placeholder"日期" format"YYYY/M/D" value-format"YYYY/M/D" style"width: 100%;" :disabled-date"publishDateAfter" > </el-dat…...
【Docker】 常用命令
文章目录 介绍Docker和容器化技术什么是Docker?Docker的优势和应用场景Docker的应用场景包括但不限于: 安装和配置Docker安装Docker引擎配置Docker环境 Docker镜像命令搜索镜像拉取镜像查看本地镜像删除本地镜像 Docker容器命令创建容器启动容器停止容器…...

docker compose - 设置名字
只使用 docker compose up 启动容器,默认名字为当前文件夹的名字 设置 project-name,docker 客户端会显示设置的名字,方便区分 docker compose --project-name webtest up错误: docker compose up --project-name webtest 效果…...

工业拍卖平台、信息发布、租赁商城平台系统适用于全行业解决方案。
工业拍卖平台系统是为工业领域的资产交易、设备处置等提供线上拍卖服务的数字化平台。 主要功能: 拍卖信息发布:平台会展示待拍卖的工业资产详细信息,包括设备的名称、型号、规格、使用年限、生产厂家等基本信息,以及资产的图片…...
一个win32 / WTL下多线程库(CThread类)的使用心得
说是多线程库,其实就是一个单独的.h文件,可以方便的放入WTL/win32工程中。 下载地址:CThread. 里面也简单介绍了 用法。 具体用法,首先自定义一个子线程类继承CThreadImpl<T>,注意他是个模板类。 class CMySu…...

使用wordpress搭建简易的信息查询系统
背景 当前有这样的一个需求,要实现让客户能够自助登录系统查询一些个人的信息,市面上没有特别符合我的需求的产品,经过一段时间的研究,想出了一个用wordpress实现简易信息查询系统,有两种方式。 方式一:使…...

PAT甲级 1076 Forwards on Weibo(30)
文章目录 题目题目翻译深度优先搜索(dfs)宽度优先搜索(bfs)总结 原题链接 题目 题目翻译 微博被称为中国的推特。在微博上,一个用户可能有很多粉丝,也可能关注许多其他用户。因此,通过粉丝关系…...
揭开 gRPC、RPC 、TCP和UDP 的通信奥秘
差异点 特性TCPUDPRPCgRPCHTTP工作层级传输层传输层应用层应用层应用层传输协议面向连接的传输协议无连接传输协议使用 TCP、HTTP 等协议HTTP/2HTTP/1.1, HTTP/2序列化格式字节流数据报文XML、JSON 或自定义Protocol BuffersJSON 或 XML特点可靠的连接传输无连接、快速传输远程…...
使用Web Worker来处理多线程操作,以及如何避免主线程卡顿。
在JavaScript中处理大量数据时,由于JavaScript是单线程的,所有的操作都在主线程上运行,因此处理大量数据可能导致页面卡顿和响应迟缓。为了避免这些问题,可以使用Web Workers来实现多线程操作,允许在后台线程中处理复杂…...

杂谈:业务说的场景金融是什么?
引言:市场格局的转变 在供应短缺的年代,是典型的卖方市场。为了保证稳定供货,买方会提前一段时间下单,也几乎没什么议价能力。卖方只需等着接单就行。 现在很多领域的供应商数量越来越多,而且随着互联网的普及&#…...

在vscode实现用和Chrome开发者工具中相同的快捷键进行面板切换
在Chrome开发者工具中,我们可以用 Ctrl [ 和 Ctrl ] 快捷键来切换面板,用起来很方便。 vscode中默认没有这两个快捷键,我们可以通过配置自定义快捷键来实现相同的功能。 配置方法: 1. 按 Ctrl K, Ctrl S 调出快捷键配置面板。…...
【ESP32+MicroPython】硬件控制基础
ESP32是一款功能强大的微控制器,具有多种硬件接口。本文以“ESP32硬件控制”为主题,逐步介绍GPIO(通用输入输出)、PWM(脉宽调制)、ADC(模数转换)等功能的原理与实现,并结…...

Python学习从0到1 day26 第三阶段 Spark ① 数据输入
要学会 剥落旧痂 然后 循此新生 —— 24.11.8 一、Spark是什么 定义: Apache Spark 是用于大规模数据处理的统一分析引擎 简单来说,Spark是一款分布式的计算框架,用于调度成百上千的服务器集群,计算TB、PB乃至EB级别的海量数据…...
kafka消费者的消费分区策略有哪些,默认是哪个?
Kafka消费者的分区分配策略主要有以下几种,分别决定了如何将多个分区分配给消费者: 1. Range(范围分配) 描述:将分区连续地分配给消费者。每个消费者负责一段连续的分区。如果有多个消费者,那么消费者会按…...
前端常用时间操作汇总
(1)获取中国标准时间: let now new Date(); // Thu Nov 14 2024 17:13:49 GMT0800 (中国标准时间) (2)获取年份: let year now.getFullYear(); // 2024 (3)获取月份&…...

106. UE5 GAS RPG 使用MVVM
MVVM 是 Model-View-ViewModel的缩写,个人理解它和MVC很相似,有区别的地方在于,在MVC里,Controller会服务多个View,而MVVM里,每个View都拥有一个单独的ViewModel,所以ViewModel相当于精简版的Co…...

Elasticsearch中什么是倒排索引?
倒排索引(Inverted Index)是一种索引数据结构,它在信息检索系统中被广泛使用,特别是在全文搜索引擎中。倒排索引允许系统快速检索包含给定单词的文档列表。它是文档内容(如文本)与其存储位置之间的映射&…...
深度学习:AT Decoder 详解
AT Decoder 详解 在序列到序列的模型架构中,自回归解码器(Autoregressive Translator, AT Decoder)是一种核心组件,其设计目标是确保生成的序列在语义和语法上的连贯性与准确性。自回归解码器通过逐步、依赖前一输出来生成新的输…...
pythons工具——图像的随机增强变换(只是变换了图像,可用于分类训练数据的增强)
从文件夹中随机选择一定数量的图像,然后对每个选定的图像进行一次随机的数据增强变换。 import os import random import cv2 import numpy as np from PIL import Image, ImageEnhance, ImageOps# 定义各种数据增强方法 def random_rotate(image, angle_range(-30…...

c++ decltype关键字
decltype为类型推导关键字。 示例代码: // decltype也可用于函数模板编程: template<typename T, typename U> auto add(T t, U u) -> decltype(t u) {return t u; }// decltype推导函数返回类型 auto doubleNumFunc(int x) -> decltype(x * 2) {ret…...

自然语言处理——语言模型
语言模型 n元文法参数估计数据平滑方法加1法 神经网络模型提出原因前馈神经网络(FNN)循环神经网络 n元文法 大规模语料库的出现为自然语言统计处理方法的实现提供了可能,统计方法的成功应用推动了语料库语言学的发展。 语句 𝑠 …...

1 Studying《蓝牙核心规范5.3》
目录 [Vol 0][Part B 蓝牙规范要求] 3 定义 3.1 蓝牙产品类型 4 核心配置 4.1 基本速率核心配置 4.2 增强型数据速率核心配置 4.4 低功耗核心配置 4.5 基本速率和低功耗结合的核心配置 4.6 主机控制器接口核心配置 [Vol 1][Part A 架构]1 概述 1.1 BR/EDR操作概述 …...
用 Lazarus IDE 写一个邮件客户端软件,能收发邮件,编写邮件
下面是一个使用Lazarus IDE开发的基本邮件客户端实现方案,包含收发邮件和编写邮件的核心功能。我们将使用Synapse库(跨平台的网络通信库)来处理邮件协议。 步骤1:安装依赖 安装Synapse库: 下载地址:https:…...
nano编辑器的详细使用教程
以下是 Linux 下 nano 编辑器 的详细使用指南,涵盖安装、基础操作、高级功能、快捷键以及常见问题处理。 一、安装 nano 大多数 Linux 发行版已预装 nano。如果没有安装,可以通过以下命令安装: Debian/Ubuntu 系:sudo apt update…...

LLMs 系列科普文(5)
在前文中,我们讲述了什么是基础模型,并重点以 LLaMA 3.1 基础模型为例,向大家演示了它可以做什么,有哪些问题或有趣的现象。 在进入新的主题内容之前,我们再次对 基础模型 做一些总结: 这是一个基于 toke…...

量子计算导论课程设计 之 PennyLane环境搭建
文章目录 具体配置conda 虚拟环境配置Pennylane 正所谓,磨刀不误砍柴工,想要进行量子计算导论的课程设计,首先就是搭建好平台,推荐大家就是本地搭建,那么下面有三种选择 QiskitTensorFlow QuantumPennylane 具体配置…...
PyCharm和VS Code哪个更适合初学者
对于 Python 初学者来说,选择 VS Code 还是 PyCharm 取决于你的具体需求和使用场景。以下是两者的详细对比和推荐建议: VS Code 优点: 轻量级:启动速度快,占用资源少,适合在低端设备上运行。高度可定制&am…...
(新手友好)MySQL学习笔记(6):分组查询,正则表达式
目录 分组查询 创建分组 过滤分组 分组查询练习 正则表达式 匹配单个实例 匹配多个实例 正则表达式练习 练习答案 分组查询练习答案 正则表达式练习答案 分组查询 创建分组 group by 子句:根据一个或多个字段对结果集进行分组,在分组的字段上…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(上)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...