C#初级知识——List和Dictionary(一些笔记)

2023-11-11

C#初级知识——List和Dictionary(一些笔记)


前言

初学一些C#的一些知识总结,主要是看擅码网的Monkey老师的3D学习路线第一部分中的《C#初级课程之数据结构》这一块内容。并没有包含所有的知识点讲解,只是记录一些自己觉得应该注意的点。

所有代码均在VS2019中完成。毕竟还是新手,如果有些语句叙述并不严谨到位,还请各位大佬指正。


一、什么是集合结构?

C#中提供了一系列特殊功能的类,这些类可以存储任意类型的对象,并且长度是可变的,他们统称为集合。

在C#语言中,集合结构有两种:泛型集合非泛型集合

  1. 泛型集合,只能存储固定类型的对象的一种集合。
    C# 语言中泛型集合是泛型中最常见的应用,主要用于约束集合中存放的元素。 由于在集合中能存放任意类型的值,在取值时经常会遇到数据类型转换异常的情况,因此推荐在定义集合时使用泛型集合。
    后面主要讲List集合和Dictionary集合。
  2. 非泛型集合。它可以存储多种类型的对象,其中最常用的是ArrayList集合和Hashtable集合

二、List集合

1.介绍

List泛型集合是C#编程中的经常使用的集合之一。

List集合的本质是和数组一样,即List集合这个类的内部其实就是维护了一个数组,但是它比数组灵活。List这个类封装了很多能够操作这个内部数组的各种方法,我们可以很方便的对数据进行增、删、改等操作。而且其长度可以动态改变。和数组相比,它也可以动态的添加元素而不是声明的时候就必须指定大小。

2.语法相关

1. 创建List泛型集合

List集合是C#内置的一个类,是类就可以实例化出对象。

首先入引命名空间

using System.Collections.Generic

然后实例化

List<类型> 集合名 = new List<类型>();
2.集合数据操作

相关数据操作即为非常经典的增、删、查、改。

  1. 增加数据
    往集合中添加,数据会不断的添加到集合中,形成一种类似于排队的效果。
集合名.Add(Value)
  1. 查询数据
    List集合的索引和数组,也是从0开始;
    也可以通过".Count"来取得
Console.WriteLine(集合名[索引]) //这样就能输出集合中对应的数据
Console.WriteLine(集合名.Count) //这样就能输出集合的长度
  1. 删除数据
    指定索引,并删除索引位置的数据,如果改索引被删除后,该索引后面的数据的索引会动被调整
a = 1;
集合名.RemoveAt(a)
  1. 修改数据
    给定索引,重新复制
集合名[索引] = 新值;

代码如下(示例):

///实例化一个集合
            List<int> num = new List<int>();
            
            
            //添加了一个数据
            num.Add(5);
            num.Add(15);
            num.Add(25);
            Console.WriteLine(num[1]);

            //读取数据
            for (int i = 0;i<num.Count;i++)
            {
                Console.WriteLine(num[i]);
            }

            Console.WriteLine("----------");
            
            //删除数据,中间填的是位置
            num.RemoveAt(2);
            for (int i = 0; i < num.Count; i++)
            {
                Console.WriteLine(num[i]);
            }

            //修改数据
            num[0] = 100;
            Console.WriteLine("----------");
           
            for (int i = 0; i < num.Count; i++)
            {
                Console.WriteLine(num[i]);
            }

代码执行结果如下:
在这里插入图片描述

3. List集合管理对象

List集合所能操作的类型,不止常见的string、int等等,还可以是类

下面将展示一段关于List集合管理对象的示例:

  1. 先添加一个武器类:
    ① 定义字段id、name、attack(攻击力属性);
    ② 然后进行属性封装;
    ③ 再构造含有三个字段的构造方法;
    ④ 最后改写ToString()方法,使其在调用类名进行输出的时候能够输出武器的相应信息。
class Weapon
    {
        private int id;
        private string name;
        private int attack;

        public Weapon(int id, string name, int attack)
        {
            this.id = id;
            this.name = name;
            this.attack = attack;
        }

        public int Id { get => id; set => id = value; }
        public string Name { get => name; set => name = value; }
        public int Attack { get => attack; set => attack = value; }

		//改写ToString()方法
        public override string ToString()
        {
            return string.Format("id:{0},name:{1},attack:{2}", this.id, this.name,this.attack);
        }

    }
  1. 然后在Program.cs中,进行数据的输出。
    (这里夹带了私货,所采用的例子均出自手游《原神》,武器数值均为瞎填,勿究)
class Program
    {
        static void Main(string[] args)
        {
            //武器集合的定义
            List<Weapon> weapons = new List<Weapon>();

            //实例化一把武器,这是一种方式,可以简写
            Weapon item = new Weapon(1,"弓藏",510);
            weapons.Add(item);

            weapons.Add(new Weapon(2, "铁锋针", 165));
            weapons.Add(new Weapon(3, "祭礼剑", 56));
            weapons.Add(new Weapon(4, "匣里灭辰",201));

			//输出一下
            for (int i = 0; i < weapons.Count; i++)
            {
                Console.WriteLine(weapons[i]);
            }

            //分割线
            Console.WriteLine("---------------------");

            //按照索引删除
            weapons.RemoveAt(1);

            //按内容删除,需要遍历集合
            for (int i = 0; i < weapons.Count; i++)
            {
                if (weapons[i].Name == "祭礼剑")
                {
                    //不仅可以删除,也可以修改
                    weapons.Remove(weapons[i]);
                    weapons[i].Attack = 31;
                }
            }


            //遍历集合
            //直接这样子输出,有18个重载方式
            for (int i = 0; i < weapons.Count; i++)
            {
                Console.WriteLine(weapons[i]);
            }
        }
    }

结果如下:
在这里插入图片描述

  1. 这里要提一下关于Wepon类里面override ToString()方法的问题。如果在Weapon类里面不进行改写的话,输出的结果会变成如下:
    在这里插入图片描述
    可以看到的是,Weapon[i]的输出全变成了项目名+类名。
    这个时候,将鼠标放在Program.cs中cw上,会有这样一行字:
    在这里插入图片描述
    因为这样输出会有18个重载,系统默认调用ToString方法来进行输出,就会出现后面那张图的输出。
    ToString方法
    ① ToString 方法返回一个对象实例的字符串,在默认情况下将返回类类型的限定名。
    ② C# 中几乎所有的类型都派生自 Object,所以如果当前类型没有重写 ToString() 方法的情况下,调用 ToString() 方法,默认返回当前类型的名称。
    ③ 任何类都可以重写 ToString 方法,返回自定义的字符串。对于其他的值类型,则为将值转换为字符串类型的值。

这个时候就需要改写一下ToString类,让其输出我们想要的输出:

public override string ToString()
{
	return string.Format("id:{0},name:{1},attack:{2}", this.id, this.name, this.attack);
}

之后结果就能正常输出啦!

4.MVC模式

1.MVC介绍

MVC是软件开发行业比较经典的设计模式,那是一种代码开发的思想和套路,将要实现的某个功能分成三个部分:

  1. V:View[视图层],也就是界面,主要负责和用户进行输入输出的交互;
  2. C:Controller[控制器层],负责处理该功能的逻辑部分;
  3. M: Model[模型层],进行数据操作。

可以进一步理解为,V提供可视化界面,C接收用户命令之后,调用各种方法,告诉后台数据应该怎样处理,M按照C的要求处理数据。

以网站登录页面为例进行说明:
登录页面(V)<----> 登录,注册(C)<----> 数据库相关操作(M)

2.代码模式

MVC模式具有三个模式,我们将进行对用户信息的增、删、查、改功能,这里将只放一个框架,具体代码会另开一篇文章具体描述(言外之意就是写的还不完善,哎嘿~)。

  1. 首先,因为我们对用户进行操作,所有我们需要一个用户类,添加User类:
class User
    {
        private string name;//用户姓名
        private int age;//用户年龄
        private string address;//用户地址
        
		///无参的构造函数
        public User(){}
        
		///有参的构造函数
        public User(string name, int age, string address)
        {
            this.name = name;
            this.age = age;
            this.address = address;
        }
		
		//对字段进行封装
        public int Name{ get => name; set => name = value; }  
        public int Age { get => age; set => age = value; }
        public string Address { get => address; set => address = value; }

		//改写ToString方法
        public override string ToString()
        {
            return string.Format("{0}|{1}|{2}", this.name, this.age,this.address) ;
        }

    }
  1. User类创建好了之后,我们还需要一个一个控制器,UserController类。
    这边将只放出框架,各个方法内部都是调用List集合的方法,或者还进行一些数据的筛选以及为了增强程序的健壮性而进行的逻辑判断。详细会在另一篇放出。
class UserControler
{
      //实例化一个用户集合
      List<User> userList = new List<User>();
      /// 上面的集合是内部的一个数据集合,是不能对外公布的,即使是再简单的操作,也用public进行封装

      /// <summary>
      /// 添加数据
      /// </summary>
      /// <param name="user"></param>
      public void AddItem(User user) {}
      
      
      //删除数据
      //删除数据将使用两种删除方法
      //一种是按地址删除,一种是按用户名字删除
      
      /// <summary>
      /// 按用户名字删除
      /// </summary>
      public void RemoveName(string name){ }

      /// <summary>
      /// 按用户地址删除数据
      /// </summary>
      public void RemoveAddress(string address){ }

      //修改数据
      public void AlterInfo(string name,string address) { }

      //查找数据
      public void ShowAll() { }
  }
  1. 同样的,提供给用户交互界面的视图层,同样也只提供一个框架。
/// <summary>
/// 视图层
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
    Console.WriteLine("----------------------");
    Console.WriteLine("-----用户管理系统-----");
    Console.WriteLine("----------------------");

    Console.WriteLine("1.添加用户信息");
    Console.WriteLine("2.修改用户信息");
    Console.WriteLine("3.删除用户信息");
    Console.WriteLine("4.查看用户信息");
    Console.WriteLine("5.退出系统");

    //需要实例化一个UserController控制器对象
    UserControler uc = new UserControler();
    #endregion

    while (true)
    {
        
        Console.Write("请选择你需要执行的功能:");
        //接受用户输入的数据
        string userInput = Console.ReadLine();

        //对用户输入的数据进行判断
        switch (userInput)
        {
            case "1":
                {
                 //姓名
                 string n = Console.ReadLine();
                 //年龄
                 int a = Convert.ToInt32(Console.ReadLine());
                 //地址
                 string ad = Console.ReadLine();
                 //调用控制器中的方法,将数据添加进集合
                 uc.AddItem(new User(name, age, address));
                }
                break;
            case "2":
                {
                	string nA = Console.ReadLine();;//需要查找的名字
                	string adAlter=Console.ReadLine();//需要修改成的地址
                	uc.AlterInfo(nA, adAlter);
                }
                break;
            case "3":
            	{    	
            		//按姓名删
	                string nameInputRemove = Console.ReadLine();
	                uc.RemoveName(nameInputRemove);
	                
	                //按地址删
	                string addressInputRemove = Console.ReadLine();
	                uc.RemoveName(addressInputRemove);
	               
	                break;
                        
                    
                }
                break;
            case "4":
                uc.ShowAll();
                break;
            case "5":
                break;
            default:
                Console.WriteLine("您输入的格式不对,请重新输入QvQ!");
                Console.WriteLine();
                break; 
        }
    }

}
   

3. Dictionary介绍

1. Dictionary集合介绍

Dictionary集合是一种“键值对”集合,它包含在System.Collections.Generic名空间中:

  1. 从一组键(Key)到一组值(Value)的映射,每一个添加项都是由一个值及其相关连的键组成

  2. 任何键都必须是唯一的

  3. 键不能为空引用null(VB中的Nothing),若值为引用类型,则可以为空值

  4. Key和Value可以是任何类型(string,int,custom class 等)

2. Dictionary集合的基本使用

1. 创建Dictionary泛型集合
  1. 首先映入命名空间:
    using System.Collections.Generic;
  2. 创建集合
    Dictionary<K类型,V类型> 集合名 = new Dictionary<K类型,V类型>();
2. 集合数据操作
  1. 增加数据
    往集合中添加数据,由于Dictionary的键是唯一的,不能添加两个同键名的数据。
    集合名.Add(K,V)

  2. 查询数据
    取出指定键名对应的数据,以及获取集合的长度。 信息
    xxx = 集合名[键名]
    yyy = 集合名.Count

  3. 修改数据
    给指定键名所对应的数据重新赋值。
    集合名[键名] = 新值;

  4. 删除数据
    删除指定键名所对应的数据。
    集合名.Remove(键名)

  5. 遍历字典
    字典没有角标,是通过键来索引的,所有选择用foreach

foreach (var item in dic.Keys)
{
	Console.WriteLine("{0}:{1}",item,dic[item]);
}
3. Dictionary 常用方法
  1. 判断当前字典集合中是否包含某个键,返回bool值。
    ContainsKey(K)

  2. 判断当前字典集合中是否包含某个值,返回bool值。
    ContainsValue(V)

示例代码如下:
4. 选择一个类MVC模式,来管理电话本,添加一个phoneController类

/// <summary>
    /// C.控制器
    /// </summary>
    class PhoneController
    {
        //定义一个字典集合<姓名,电话号码>
        Dictionary<string, string> phones = new Dictionary<string, string>();

        //增
        /// <summary>
        /// 添加数据
        /// </summary>
        /// <param name="name">姓名</param>
        /// <param name="phoneNumber">电话号码</param>
        public void AddItem(string name,string phoneNumber)
        {
            phones.Add(name, phoneNumber);
        }

        //删
        /// <summary>
        /// 通过名字删除号码
        /// </summary>
        /// <param name="name">姓名</param>
        public void DelItem(string name)
        {
            phones.Remove(name);
        }


        //查
        /// <summary>
        /// 显示所有的字典信息
        /// </summary>
        public  void ShowAll()
        {
            foreach (var item in phones.Keys)
            {
                Console.WriteLine("{0}:{1}",item,phones[item]);
            }
        }

        //改
        public void UpdateItem(string name,string number)
        {
            phones[name] = number;
        }
		
		//判断键是否存在
        public void SearchKeys(string name)
        {
            if (phones.ContainsKey(name))
            {
                Console.WriteLine("{0}这个键存在!", name);
            }
            else
            {
                Console.WriteLine("{0}这个键不存在!", name);
            }
        }

        //判断值是否存在
        public void SearchValues(string number)
        {
            if (phones.ContainsValue(number))
            {
                Console.WriteLine("{0}这个值存在!", number);
            }
            else
            {
                Console.WriteLine("{0}这个值不存在!", number);
            }
        }
       

    }
  1. 在Program.cs中
class Program
{
    /// <summary>
    /// view视图类
    /// </summary>
    /// <param name="args"></param>
    static void Main(string[] args)
    {
        PhoneController pc = new PhoneController();
        //添加
            pc.AddItem("达达利亚", "11111111");
            pc.AddItem("胡桃", "22222222");

            //查询
            pc.ShowAll();

            Console.WriteLine("------------------------");
            //更改
            pc.UpdateItem("胡桃", "333333333");

            //删除
            pc.DelItem("胡桃");

            pc.ShowAll();

            Console.WriteLine("------------------------");

            //判断键是否存在
            pc.SearchKeys("达达利亚");
            pc.SearchKeys("胡桃");

            //判断值是否存在
            pc.SearchValues("11111111");
            pc.SearchValues("22222222");

            Console.ReadKey();

    }
}

代码执行结果如下:
在这里插入图片描述


总结

简单学习了List和Dictionary集合的使用,关于MVC用户管理系统详细的写法会另开一个文档。

之后也将继续学习C#的其他数据结构,如链表,队列,栈,二叉树,图等等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C#初级知识——List和Dictionary(一些笔记) 的相关文章

随机推荐

  • spring和servlet之间得关系

    servlet filter和listener是javaweb得三大组成部分 其中servlet通常是由web xml统一管理 而springmvc核心是disparcherservlet为入口 spring可以管理servlet和spri
  • 自旋锁 互斥锁 读写锁 递归锁

    互斥锁 mutexlock 最常使用于线程同步的锁 标记用来保证在任一时刻 只能有一个线程访问该对象 同一线程多次加锁操作会造成死锁 临界区和互斥量都可用来实现此锁 通常情况下锁操作失败会将该线程睡眠等待锁释放时被唤醒 自旋锁 spinlo
  • (个人记录)简单的selenium实现自动点击

    主要目标 网页需要每五分钟手动点击确认弹窗 为实现自动化点击以写此代码 环境需求 本代码采用的Chrome浏览器 采用selenium 将对应Chrome版本的selenium exe安装入python目录下 如无法运行可以在python终
  • python正则表达式(.*?)的理解

    在Python开发爬虫过程中经常会遇到正则表达式 其中 的使用概率较高 那么这个正则表达式到底什么意思呢 表示非贪心算法 表示要精确的配对 表示贪心算法 表示要尽可能多的匹配 表示要获取括弧之间的信息 用一个例子来说明一下 import r
  • java中HTTP的返回状态码

    返回状态码 author ruoyi public class HttpStatus 操作成功 public static final int SUCCESS 200 对象创建成功 public static final int CREAT
  • wpf自定义控件之双滑块Slider

    效果
  • 【FPGA】五、蜂鸣器播放音乐

    文章目录 前言 一 蜂鸣器简介 二 音频音符简介 三 任务要求 四 程序设计 1 设计思路 2 程序代码 总结 前言 蜂鸣器 Buzzer 是现代常用的一种电子发声器 主要用于产生声音信号 它是一种一体化结构的电子讯响器 采用直流电压供电
  • Python手册(Visualise)--seaborn

    文章目录 数据集 关系图 核心函数 散点图 折线图 分面图 分布图 核心函数 直方图 核密度估计 经验累积分布 地毯图 二元分布 分类图 核心函数 散点图 分布图 统计图 回归图 矩阵图 热力图 聚类图 网格图 分面网格 配对网格 联合网格
  • blockchain java_blockchain-java(简易区块链项目)

    blockchain java 简易区块链项目 是基于Java实现的一个简易区块链 联盟链 项目 包括加密工具 钱包 P2P 传输 区块同步 POW 共识等基础实现 使用方法 单节点部署 这个很简单 直接像运行普通的 SpringBoot
  • d3dUtility.cpp 统一回答:在vs2015中调试D3D9龙书 代码示例:4.4 d3dUtility.cpp

    龙书d3d9的代码 在作者的资源中 可查找 免分 注意 如果可能的话 请先安装DXSDK Jun10 exe 然后再安装VS2010或VS2015 否则 会在安装DXSDK Jun10 exe的过程的最后阶段会报错 不过 即使是报错 也不影
  • <稀缺-我们是如何陷入贫穷与忙碌的> 摘要

    2015 07 08 10 12 lt 稀缺 我们是如何陷入贫穷与忙碌的 gt 摘要 这本书分析了稀缺的内在来源和所造成的影响 列举了许多例子 下面我把它的核心思想记录一下 稀缺心态是一切稀缺的根源 资源稀缺并不可怕 就怕有稀缺心态 以后简
  • Ubuntu20.04下显卡驱动安装的完整过程(超详细)

    1 首先查看硬件 显卡是否安装 lspci grep i vga lspci grep i nvidia 注意 如果没显示显卡信息则看显卡是否安装好 看下显卡风扇是否在转 图中是显卡位置 然后再执行上面的命令 确定显卡安装没问题了之后 再看
  • VMware Workstation无法提供该虚拟机所需的所有图形功能

    报错信息 VMware Workstation无法提供该虚拟机所需的所有图形功能 在该虚拟机引导后 图形硬件 图形驱动程序或Vware软件版本可能已发生变化 该虚拟机将继续运行 但在关闭该虚拟机之前 某些图形操作可能会出现不可预见的行为 原
  • replace将逗号换成分好 vue_使用replace()方法替换一段文字中的某一个字符串

    一 replace 方法的第二个参数为字符串时 1 第一个参数为字符串 替换匹配到的第一个字符串 var str 段落这是一个段落 str replace 段落 段落 2 第一个参数为正则表达式时 替换所有匹配到的字符串 var str 段
  • 电脑连接不上网络(梯子原因)

    1 问题描述 2 具体原因 使用梯子造成的 具体原因没有深究 3 解决办法 控制面板 网络和Internet Internet选项 连接 局域网设置 在代理服务器处取消勾选为LAN使用代理服务器 这些设置不用于拨号或VPN连接 X
  • react-draggable实现拖拽详解

    react draggable 属性 常用属性 属性列表 事件列表 举例 首先安装 react draggable 实现移动 希望小编写的能够帮助到你 属性 常用属性 属性 默认值 介绍 axis x handle拖动的方向 可选值 x y
  • Abbirb120型工业机器人_ABB机器人IRB120资料的详细介绍

    ABB机器人IRB120资料的详细介绍 在工业4 0时代 越来越多机器人投身于生产一线 ABB机器人作为全球 的机器人品牌 受到众多企业的关注 近期有很多朋友都在质疑abb IRB120这个型号的机器人性能如何 接下来就由专业人士为大家带来
  • dialog BLE SDK 学习(3)

    dialog DA14580 SDK版本 5 0 4 本文介绍了DA14580 SDK的学习感想和建议 分享给大家 首先 Dialog官网上的资料挺全的 但是是英文的 如果英文不好 比如笔者 阅读起来是件痛苦的事情 资料都挺好的 唯一的不足
  • 华为手机怎么连接苹果电脑?

    华为手机怎么连接苹果电脑 https zhidao baidu com question 1946793458712978108 html 连接之后 在mac上面进行安装dmg文件 然后就有了一个读取android文件的应用 然后就可以查看
  • C#初级知识——List和Dictionary(一些笔记)

    C 初级知识 List和Dictionary 一些笔记 文章目录 C 初级知识 List和Dictionary 一些笔记 前言 一 什么是集合结构 二 List集合 1 介绍 2 语法相关 1 创建List泛型集合 2 集合数据操作 3 L