C#进阶学习-Day2

今日学习了:泛型约束、泛型数据集合List、LinkedList、Dictionary、Stack、Queue、顺序存储和链式存储

1.泛型约束

目的:让泛型类型有一定的限制

关键字:where

六种泛型约束

1.值类型        where 泛型字母:struct

2.引用类型        where 泛型字母:class

3.存在公共无参构造方法的非抽象类型        where 泛型字母:new()

4.某个类本身或其派生类        where 泛型字母:类名

5.某个接口的派生类型(可以是接口本身或者派生接口也可以是实现的类,是接口本身或派生接口因为接口无法实例化使用时涉及里氏替换原则) where 泛型字母:接口名

例如:

    interface IFly
    {

    }
    interface IMove :IFly { }

    class test4 :IMove
    {

    }
    class Move<T> where T : IFly 
    {
        public T Value { get; set; }
    }
    //    Move<IMove> move = new Move<IMove>();
    //    move.Value = new test4();

   6.另一个泛型类型本身或者派生类型        where 泛型字母:另一个泛型字母

约束的组合使用
    class Test7<T> where T : IFly,new()
    {

    }

多个泛型约束
    class Test8<T,K> where T:IFly,new() where K : T, new()
    {

    }

2.List
 List的本质是可变类型的泛型数组,实现了很多方法

List的声明
          List<int> list = new List<int>();

增删查改

增:
          list.Add(10);        单个增到后面

          list.Insert(0,2);        Insert()指定下标位置插入元素

          list.AddRange(list2);        AddRange()把另一个list里的内容加到后面

删:
          list.Remove(10);        从头找删掉指定元素,如果有多个1,会删除第一个1

          list.RemoveAt(0);        移除指定下标位置的元素

          list.Clear();                清空


          Console.WriteLine(list[0]);//[下标]查找指定下标元素
          if(list.Contains(1))        //查找list存不存在指定元素
          {
              Console.WriteLine("存在元素1");
          }

          Console.WriteLine(list.IndexOf(1));从前往后找指定元素并返回其下标,如果不存在返回-1,如果有多个指定元素,返回从前往后第一个
          Console.WriteLine(list.LastIndexOf(1));//从后往前找指定元素并返回其下标,如果不存在返回-1,如果有多个指定元素,返回从后往前第一个
          Console.WriteLine(list.Capacity);//.Capacity存储容量,是List种数组的实际容量,.Count的为当前所存储的元素个数

改:

        list[0] = 10;//直接修改

简述List和ArrayList的区别
        List内部封装的是一个泛型数组,ArrayList内部封装的是一个Object数组

3.Dictionary

Dictionary的本质
        可以理解为拥有泛型的Hashtable
        它也是基于键的代码组织起来的键值对
       键值对由Hashtable的object变成了可以自己指定的泛型

声明
        Dictionary<int,string> keyValuePairs = new Dictionary<int,string>();

增删查改


        keyValuePairs.Add(1, "123");
        //同样不能添加以及存在的相同的key,否则运行会报错
        //keyValuePairs.Add(1, "234");

1.只能通过键去删除
        keyValuePairs.Remove(1);
        keyValuePairs.Remove(4);//同样没有对应的key不做反应
2.清空
        keyValuePairs.Clear();

1.通过键来查找
        找不到,不同于Hashtable返回空,这里会报错

        Console.WriteLine(keyValuePairs[1]);

2.查看是否存在
        //根据键检测
        if(keyValuePairs.ContainsKey(0))
        {
            Console.WriteLine("存在key为0的");
        }
        //根据值检测
        if(keyValuePairs.ContainsValue("123")) 
        {
            Console.WriteLine("存在值为\"123\"的键值对");
        }


        keyValuePairs[1] = "555";

遍历:

foreach遍历keys:

        foreach(int i in keyValuePairs.Keys) {
            Console.Write(i+":");
            Console.WriteLine(keyValuePairs[i]);
        }

foreach遍历values:
        foreach(string st in keyValuePairs.Values)
        {
            Console.WriteLine(st); 
        }

foreach遍历KeyValuePair<>:
        foreach (KeyValuePair<int,string> obj in keyValuePairs) {
            Console.WriteLine(obj);
        }

4.顺序存储与链式存储

数据结构
    数据结构是指相互之间存在一种或者多种特定关系的数据元素的集合

    "面试常考":常用的数据结构 数组、栈、队列、链表、树、图、堆、散列表

    线性表 是由n个具有相同特性的数据元素的有限序列
    比如数组、ArrayList、Stack、Queue、链表等等

    顺序存储和链式存储
    顺序存储:用一组地址连续的存储单元一次存储线性表的各个数据元素
    链式存储:
    单向链表,双向链表,循环链表 --链式存储
    用一组任意的存储单元存储线性表的各个数据元素

    顺序存储和链式存储的优缺点
    从增删改查的角度思考
    增:链式存储 计算上 优于顺序存储 (中间插入时不用像数组一样去依依移动元素位置)
    删:链式存储 计算上 优于顺序存储 (中间删除时不用像数组一样去依依移动元素位置)
    查:顺序存储 使用上 优于链式存储 (数组可以直接通过下标得到元素,链式需要遍历
    改:顺序存储 使用上 由于链式存储 (数组可以直接通过下标得到元素,链式需要遍历)

描述顺序存储和链式存储的区别
        顺序存储的存储内存地址是连续的(连续地址存储)
        链式存储的存储内存地址是随机的(任意地址存储)

实现一个双向链表,并提供以下方法属性,数据的个数,头节点,尾节点,增加数据到链表最后,删除指定位置节点:

class LinkedNode<T>
{
    public T Value;
    public LinkedNode<T> nextNode;
    public LinkedNode<T> preNode;
    public LinkedNode(T Value)
    {
        this.Value = Value;
    }
}

class LinkedList<T>
{
    public LinkedNode<T> head;
    public LinkedNode<T> last;
    public int Count { get; private set; }
    public LinkedList()
    {
        Count = 0;
    }
    public void Add(T Value)
    {
        LinkedNode<T> Node = new LinkedNode<T>(Value);
        if (head == null)
        {
            head = Node;
            last = Node;
        }else
        {
            last.nextNode = Node;
            Node.preNode=last;
            last=Node;
        }
        Count++;
    }
    public void Remove(T Value)
    {
        LinkedNode<T> Node = head;
        if (head.Value.Equals(Value))
        {
            head = head.nextNode;
            head.preNode = null;
            if (head == null) last = null;
            Count--;
            return;
        }
        while(Node != null)
        {
            if (Node.Value.Equals(Value))
            {
                if (Node == last)
                {
                    last = Node.preNode;
                    Node.preNode.nextNode = null;
                    Node.preNode = null;
                }
                else
                {
                    Node.preNode.nextNode = Node.nextNode;
                    Node.nextNode.preNode = Node.preNode;
                }
                Count--;
                return;
            }
            Node = Node.nextNode;
        }
    }
    public void RemoveAt(int index) 
    {
        if (index < 0 || index >= Count) return;
        Count--;
        LinkedNode<T> Node = head;
        for(int i=0;i<index;i++)
        {
            Node=Node.nextNode;
        }
        if (Node == head)
        {
            head=head.nextNode;
            head.preNode = null;
            if (head == null) last = null;
        }else if(Node == last)
        {
            last = Node.preNode;
            Node.preNode.nextNode = null;
            Node.preNode = null;
        }
        else
        {
            Node.preNode.nextNode = Node.nextNode;
            Node.nextNode.preNode = Node.preNode;
        }


    }

}

5.LinkedList

Linkedlist的本质
        是一个可变类型的泛型双向链表

申明
        LinkedList<int> list = new LinkedList<int>();

节点类型  LinkedListNode<T>

增删查改


1.在链表尾部添加元素
        list.AddLast(1);

2.在链表头部添加元素
        list.AddFirst(2);

3.在某个节点之后添加元素
        LinkedListNode<int> Node = list.Find(5);
        list.AddAfter(Node, 6);

4..在某个结点之前添加元素
        list.AddBefore(Node, 7);


1.移除头节点
        list.RemoveFirst();
2.移除尾节点
        list.RemoveLast();
3.移除指定节点

Remove(LinkedListNode<T>)

从 LinkedList<T> 中移除指定的节点。

Remove(T)

从 LinkedList<T> 中移除指定值的第一个匹配项。

4.清空
        list.Clear();


1.查到头节点
        LinkedListNode<int> first = list.First;

2.查到尾节点
        LinkedListNode<int> last = list.Last;

3.查找指定值的节点
        LinkedListNode<int> node = list.Find(5);//找不到会返回空

4.判断是否存在
        list.AddLast(1);
        if (list.Contains(1))
        {
            Console.WriteLine("存在1");
        }


        Console.WriteLine(list.First.Value);
        list.First.Value = 10;
        Console.WriteLine(list.First.Value);

遍历
1.foreach遍历 直接得到node里的value
        foreach (int item in list)
        {
            Console.WriteLine(item);
        }

 2.通过node 
        //  从头到尾
        LinkedListNode<int> temp = list.First;
        while (temp != null)
        {
            Console.WriteLine(temp.Value);
            temp = temp.Next;
        }
        temp = list.Last;
        Console.WriteLine("------------------------");
        while (temp != null)
        {
            Console.WriteLine(temp.Value);
            temp = temp.Previous;
        }

5.泛型Stack与Queue

回顾数据容器
变量 :
        无符号 byte ushort uint ulong
        有符号 sbyte short int long
        浮点数 float double decimal
        特殊
        char bool string

        复杂数据类型
        enum
        struct
        class
        数组(一维,二维,交错) [] [,] [][]

        数据集合
        ArrayList object数据列表
        Stack 栈
        Queue 队列
        Hashtable 哈希表

        泛型数据集合 用的更多
        List 泛型列表
        Dictionary 泛型哈希表
        Linkedlist 泛型双向链表
        Stack<T> 泛型栈
        Queue<T> 泛型队列

        泛型栈与队列 与 栈和队列的方法一致

        声明
        Stack<int> stack = new Stack<int>();
        Queue<int> q = new Queue<int>();

总结数组 List Dictionary Stack Queue LinkedList这些容器,如何合理使用?
        普通线性表
        数组,List,LinkedList
        数组:固定的不变的一组数据
        List:经常改变,经常通过下标查找
        LinkedList:不确定长度,经常临时插入改变,查找不多

        先进后出:
        Stack
        对于一些可以利用先进后出存储特点的逻辑
        比如:UI面板显隐规则

        先进先出
        Queue
        对于一些可以利用先进先出存储特点的逻辑
        比如:消息队列

        键值对:
        Dictionary
        需要频繁查找,有对应关系的数据
        比如一些数据存储 id对应数据内容

# 题目重述 请提供一份适合零基础学习者的 C# 学习指南,涵盖从环境搭建到进阶内容的完整路径。 --- # 详解 以下是为**零基础学习者**量身定制的 C# 全面学习路线图,循序渐进、实用性强,助你从“Hello World”成长为能开发项目的开发者。 ## 第一阶段:准备与入门(1-2周) ### 1. 安装开发环境 - **推荐工具**:[Visual Studio Community](https://visualstudio.microsoft.com/vs/)(免费) - 下载时选择 ".NET 桌面开发" 工作负载。 - 或使用轻量级工具: - **Visual Studio Code + C# 扩展** - 安装 [.NET SDK](https://dotnet.microsoft.com/download) ### 2. 编写第一个程序 ```csharp using System; class Program { static void Main() { Console.WriteLine("Hello, World!"); } } ``` > 目标:理解“运行”含义,熟悉控制台输出。 --- ## 第二阶段:核心语法基础(3-5周) ### 1. 基本数据类型 | 类型 | 示例 | |------|------| | `int` | 整数 `$10, -5$` | | `double` | 小数 `$3.14$` | | `bool` | 布尔值 `true/false` | | `string` | 字符串 `"你好"` | ### 2. 变量与常量 ```csharp int age = 20; const double PI = 3.14159; ``` ### 3. 运算符与表达式 - 算术:`+ - * / %` - 比较:`== != < >` - 逻辑:`&& || !` ### 4. 流程控制 ```csharp // 条件判断 if (age >= 18) Console.WriteLine("成年"); // 循环 for (int i = 0; i < 5; i++) Console.WriteLine(i); // switch switch (day) { case 1: Console.Write("周一"); break; } ``` ### 5. 数组与集合 ```csharp int[] nums = {1, 2, 3}; List<string> names = new List<string>(); names.Add("Alice"); ``` --- ## 第三阶段:面向对象编程 OOP(4-6周) ### 1. 类与对象 ```csharp public class Car { public string Brand { get; set; } public void Start() => Console.WriteLine("启动引擎"); } ``` ### 2. 四大特性 - **封装**:用属性保护字段 - **继承**:`class ElectricCar : Car` - **多态**:`virtual` / `override` - **抽象类与接口** > 推荐项目:设计“学生管理系统”类模型 --- ## 第四阶段:进阶技能(4-8周) ### 1. 异常处理 ```csharp try { int x = 10 / 0; } catch (DivideByZeroException) { Console.WriteLine("不能除以0"); } ``` ### 2. 文件操作 ```csharp File.WriteAllText("log.txt", "日志信息"); string content = File.ReadAllText("log.txt"); ``` ### 3. LINQ 查询 ```csharp var adults = people.Where(p => p.Age >= 18); ``` ### 4. 异步编程(async/await) ```csharp async Task DownloadAsync() { var client = new HttpClient(); string html = await client.GetStringAsync("https://example.com"); } ``` --- ## 第五阶段:实战项目(持续练习) | 项目名称 | 技能点 | |--------|-------| | 控制台计算器 | 变量、运算、循环 | | 学生成绩管理系统 | 类、集合、文件读写 | | 图书馆管理系统 | OOP、LINQ、异常处理 | | 简易记事本应用 | WinForms/WPF、文件IO | | 天气查询小程序 | HTTP 请求、JSON 解析 | --- ## 第六阶段:方向选择(学完后决定) C# 应用广泛,可选方向如下: | 方向 | 所需技术栈 | |------|-----------| | **桌面开发** | WinForms, WPF | | **游戏开发** | Unity 引擎(主语言为 C#) | | **Web 开发** | ASP.NET Core, MVC, Razor Pages | | **移动开发** | MAUI(.NET Multi-platform App UI) | --- ## 学习资源推荐 - 📘 官方文档:[learn.microsoft.com/dotnet/csharp](https://learn.microsoft.com/zh-cn/dotnet/csharp/) - 🎥 B站视频:搜索“C# 零基础 全套” - 📚 书籍:《C# 入门经典》《Head First C#- 💻 练习平台:LeetCode(简单题)、Exercism.io --- ## 学习建议 1. **每天写代码**:哪怕只有 30 分钟。 2. **先模仿再创造**:抄例子 → 改功能 → 自己写。 3. **善用调试器**:学会设置断点,观察变量变化。 4. **不要死磕**:遇到问题查资料或提问,别卡住。 --- > ✅ 总结:坚持 3 个月系统学习,即可掌握 C# 核心能力,具备开发小型项目的能力。 --- # 知识点(列出解答该问题需要的知识点) 1. **.NET 平台与 C# 关系** C# 是运行在 .NET 上的主要语言,用于构建各类应用程序。 2. **程序执行入口(Main 方法)** 所有 C# 程序从 `static void Main()` 开始执行。 3. **集成开发环境(IDE)作用** 提供代码编辑、调试、编译一体化支持,提升开发效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值