唐老狮c#进阶笔记
唐老狮c#进阶笔记
- ArrayList
using System; using System.Collections; namespace Lesson1_ArrayList { class Program { static void Main(string[] args) { #region 练习题回顾 //C#核心中 索引器的练习题 //自定义一个整形数组类,该类中有一个整形数组变量 //为它封装增删查改的方法 #endregion #region 知识点一 ArrayList的本质 //ArrayList是一个C#为我们封装好的类, //它的本质是一个object类型的数组, //ArrayList类帮助我们实现了很多方法, //比如数组的增删查改 #endregion #region 知识点二 申明 //需要引用命名空间using System.Collections; ArrayList array = new ArrayList(); #endregion #region 知识点三 增删查改 #region 增 array.Add(1); ArrayList array2 = new ArrayList(); array2.Add(123); //范围增加(批量增加 把另一个list容器里面的内容加到后面) array.AddRange(array2); array.Insert(1, "12345676"); #endregion #region 删 //移除指定元素 从头找 找到删 array.Remove(1); //移除指定位置的元素 array.RemoveAt(2); //清空 array.Clear(); #endregion #region 查 //得到指定位置的元素 Console.WriteLine(array[0]); //查看元素是否存在 if( array.Contains("1234") ) { Console.WriteLine("存在123"); } //正向查找元素位置 //找到的返回值 是位置 找不到 返回值 是-1 int index = array.IndexOf(true); Console.WriteLine(index); Console.WriteLine(array.IndexOf(false)); //反向查找元素位置 //返回时从头开始的索引数 index = array.LastIndexOf(true); Console.WriteLine(index); #endregion #region 改 array[0] = "999"; #endregion #endregion #region 遍历 //长度 Console.WriteLine(array.Count); //容量 //避免产生过多的垃圾 Console.WriteLine(array.Capacity); Console.WriteLine("***********************"); for (int i = 0; i < array.Count; i++) { Console.WriteLine(array[i]); } Console.WriteLine("***********************"); //迭代器遍历 foreach (object item in array) { Console.WriteLine(item); } #endregion #region 知识点四 装箱拆箱 //ArrayList本质上是一个可以自动扩容的object数组, //由于用万物之父来存储数据,自然存在装箱拆箱。 //当往其中进行值类型存储时就是在装箱,当将值类型对象取出来转换使用时,就存在拆箱。 //所以ArrayList尽量少用,之后我们会学习更好的数据容器。 int k = 1; array[0] = k;//装箱 k = (int)array[0];//拆箱 #endregion } } }
- Stack
#region 知识点一 Stack的本质 //Stack(栈)是一个C#为我们封装好的类 //它的本质也是object[]数组,只是封装了特殊的存储规则 //Stack是栈存储容器,栈是一种先进后出的数据结构 //先存入的数据后获取,后存入的数据先获取 //栈是先进后出 #endregion
//需要引用命名空间 System.Collections Stack stack = new Stack(); //压栈 stack.Push(1); //栈中不存在删除的概念 //只有取的概念 //弹栈 object v = stack.Pop(); //1.栈无法查看指定位置的 元素 // 只能查看栈顶的内容 v = stack.Peek(); Console.WriteLine(v); v = stack.Peek(); Console.WriteLine(v); //2.查看元素是否存在于栈中 if( stack.Contains("123") ) { Console.WriteLine("存在123"); } //栈无法改变其中的元素 只能压(存)和弹(取) //实在要改 只有清空 stack.Clear(); //1.长度 Console.WriteLine(stack.Count); //2.用foreach遍历 // 而且遍历出来的顺序 也是从栈顶到栈底 foreach(object item in stack) { Console.WriteLine(item); } //3.还有一种遍历方式 // 将栈转换为object数组 // 遍历出来的顺序 也是从栈顶到栈底 object[] array = stack.ToArray(); for (int i = 0; i < array.Length; i++) { Console.WriteLine(array[i]); } Console.WriteLine(stack.Count); //4.循环弹栈 while( stack.Count > 0 ) { object o = stack.Pop(); Console.WriteLine(o); } Console.WriteLine(stack.Count);
- Queue
#region 知识点一 Queue本质 //Queue是一个C#为我们封装好的类 //它的本质也是object[]数组,只是封装了特殊的存储规则 //Queue是队列存储容器 //队列是一种先进先出的数据结构 //先存入的数据先获取,后存入的数据后获取 //先进先出 #endregion #region 知识点二 申明 //需要引用命名空间 System.Collections Queue queue = new Queue(); #endregion #region 知识点三 增取查改 #region 增 queue.Enqueue(1); queue.Enqueue("123"); queue.Enqueue(1.4f); queue.Enqueue(new Test()); #endregion #region 取 //队列中不存在删除的概念 //只有取的概念 取出先加入的对象 object v = queue.Dequeue(); Console.WriteLine(v); v = queue.Dequeue(); Console.WriteLine(v); #endregion #region 查 //1.查看队列头部元素但不会移除 v = queue.Peek(); Console.WriteLine(v); v = queue.Peek(); Console.WriteLine(v); //2.查看元素是否存在于队列中 if( queue.Contains(1.4f) ) { Console.WriteLine("队列中存在1.4f"); } #endregion #region 改 //队列无法改变其中的元素 只能进出队列 //实在要改 只有清 Console.WriteLine(queue.Count); queue.Clear(); queue.Enqueue(1); queue.Enqueue(2); queue.Enqueue(3); #endregion #endregion #region 知识点四 遍历 //1.长度 Console.WriteLine(queue.Count); //2.用foreach遍历 foreach (object item in queue) { Console.WriteLine(item); } //3.还有一种遍历方式 // 将队列转换为object数组 object[] array = queue.ToArray(); for (int i = 0; i < array.Length; i++) { Console.WriteLine(array[i]); } //4.循环出列 while(queue.Count>0) { object o = queue.Dequeue(); Console.WriteLine(o); } Console.WriteLine(queue.Count); #endregion #region 知识点五 装箱拆箱 //由于用万物之父来存储数据,自然存在装箱拆箱。 //当往其中进行值类型存储时就是在装箱 //当将值类型对象取出来转换使用时,就存在拆箱。 #endregion
- HashTable
23using System; using System.Collections; namespace Lesson4_Hashtable { class Program { static void Main(string[] args) { Console.WriteLine("Hashtable"); #region 知识点一 Hashtalbe的本质 //Hashtable(又称散列表) 是基于键的哈希代码组织起来的 键/值对 //它的主要作用是提高数据查询的效率 //使用键来访问集合中的元素 #endregion #region 知识点二 申明 //需要引用命名空间 System.Collections Hashtable hashtable = new Hashtable(); #endregion #region 知识点三 增删查改 #region 增 hashtable.Add(1, "123"); hashtable.Add("123", 2); hashtable.Add(true, false); hashtable.Add(false, false); //注意:不能出现相同键 #endregion #region 删 //1.只能通过键去删除 hashtable.Remove(1); //2.删除不存在的键 没反应 hashtable.Remove(2); //3.或者直接清空 hashtable.Clear(); hashtable.Add(1, "123"); hashtable.Add(2, "1234"); hashtable.Add(3, "123"); hashtable.Add("123123", 12); #endregion #region 查 //1.通过键查看值 // 找不到会返回空 Console.WriteLine(hashtable[1]); Console.WriteLine(hashtable[4]);//null Console.WriteLine(hashtable["123123"]); //2.查看是否存在 //根据键检测 if( hashtable.Contains(2) ) { Console.WriteLine("存在键为2的键值对"); } if( hashtable.ContainsKey(2) ) { Console.WriteLine("存在键为2的键值对"); } //根据值检测 if( hashtable.ContainsValue(12) ) { Console.WriteLine("存在值为12的键值对"); } #endregion #region 改 //只能改 键对应的值内容 无法修改键 Console.WriteLine(hashtable[1]); hashtable[1] = 100.5f; Console.WriteLine(hashtable[1]); #endregion #endregion #region 知识点四 遍历 //得到键值对 对数 Console.WriteLine(hashtable.Count); //1.遍历所有键 foreach (object item in hashtable.Keys) { Console.WriteLine("键:"+item); Console.WriteLine("值:"+hashtable[item]); } //2.遍历所有值 foreach (object item in hashtable.Values) { Console.WriteLine("值:" + item); } //3.键值对一起遍历 foreach (DictionaryEntry item in hashtable) { Console.WriteLine("键:" + item.Key + "值:" + item.Value); } //4.迭代器遍历法 IDictionaryEnumerator myEnumerator = hashtable.GetEnumerator(); bool flag = myEnumerator.MoveNext(); while (flag) { Console.WriteLine("键:" + myEnumerator.Key + "值:" + myEnumerator.Value); flag = myEnumerator.MoveNext(); } #endregion #region 知识点五 装箱拆箱 //由于用万物之父来存储数据,自然存在装箱拆箱 //当往其中进行值类型存储时就是在装箱 //当将值类型对象取出来转换使用时,就存在拆箱 #endregion } } }
- 泛型
#region 知识点一 泛型是什么 //泛型实现了类型参数化,达到代码重用目的 //通过类型参数化来实现同一份代码上操作多种类型 //泛型相当于类型占位符 //定义类或方法时使用替代符代表变量类型 //当真正使用类或者方法时再具体指定类型 #endregion #region 知识点二 泛型分类 //泛型类和泛型接口 //基本语法: //class 类名<泛型占位字母> //interface 接口名<泛型占位字母> //泛型函数 //基本语法:函数名<泛型占位字母>(参数列表) //注意:泛型占位字母可以有多个,用逗号分开 #endregion #region 知识点三 泛型类和接口 class TestClass<T> { public T value; } class TestClass2<T1,T2,K,M,LL,Key,Value> { public T1 value1; public T2 value2; public K value3; public M value4; public LL value5; public Key value6; public Value value7; } interface TestInterface<T> { T Value { get; set; } } class Test : TestInterface<int> { public int Value { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } } #endregion class Test2<T> { public T value; public void TestFun<K>(K k) { Console.WriteLine(k); } //这个不叫泛型方法 因为 T是泛型类申明的时候 就指定 在使用这个函数的时候 //我们不能再去动态的变化了 public void TestFun(T t) { } }
- 泛型约束
- List
list.Add(1); List<string> listStr = new List<string>(); listStr.Add("123"); list2.AddRange(listStr); list.Insert(0, 999); //1.移除指定元素 list.Remove(1); //2.移除指定位置的元素 list.RemoveAt(0); //3.清空 list.Clear(); //1.得到指定位置的元素 Console.WriteLine(list[0]); //2.查看元素是否存在 if( list.Contains(1) ) { } //3.正向查找元素位置 // 找到返回位置 找不到 返回-1 int index = list.IndexOf(5); //4.反向查找元素位置 // 找到返回位置 找不到 返回-1 index = list.LastIndexOf(2); list[0] = 99; for (int i = 0; i < list.Count; i++) { Console.WriteLine(list[i]); } foreach (int item in list) { Console.WriteLine(item); }
- Dictionary
#region 知识点一 Dictionary的本质 //可以将Dictionary理解为 拥有泛型的Hashtable //它也是基于键的哈希代码组织起来的 键/值对 //键值对类型从Hashtable的object变为了可以自己制定的泛型 #endregion #region 知识点二 申明 //需要引用命名空间 using System.Collections.Generic Dictionary<int, string> dictionary = new Dictionary<int, string>(); #endregion #region 知识点三 增删查改 #region 增 //注意:不能出现相同键 dictionary.Add(1, "123"); dictionary.Add(2, "222"); dictionary.Add(3, "222"); //dictionary.Add(3, "123"); #endregion #region 删 //1.只能通过键去删除 // 删除不存在键 没反应 dictionary.Remove(1); dictionary.Remove(4); //2.清空 dictionary.Clear(); dictionary.Add(1, "123"); dictionary.Add(2, "222"); dictionary.Add(3, "222"); #endregion #region 查 //1.通过键查看值 // 找不到直接报错 Console.WriteLine(dictionary[2]); //Console.WriteLine(dictionary[4]); Console.WriteLine(dictionary[1]); //2.查看是否存在 // 根据键检测 if( dictionary.ContainsKey(4) ) { Console.WriteLine("存在键为1的键值对"); } // 根据值检测 if (dictionary.ContainsValue("1234")) { Console.WriteLine("存在值为123的键值对"); } #endregion #region 改 Console.WriteLine(dictionary[1]); dictionary[1] = "555"; Console.WriteLine(dictionary[1]); #endregion #endregion #region 知识点四 遍历 Console.WriteLine("**************"); Console.WriteLine(dictionary.Count); //1.遍历所有键 foreach (int item in dictionary.Keys) { Console.WriteLine(item); Console.WriteLine(dictionary[item]); } //2.遍历所有值 Console.WriteLine("**************"); foreach (string item in dictionary.Values) { Console.WriteLine(item); } //3.键值对一起遍历 Console.WriteLine("**************"); foreach (KeyValuePair<int,string> item in dictionary) { Console.WriteLine("键:" + item.Key + "值:" + item.Value); } #endregion
- 顺序存储与链式存储
#region 知识点一 数据结构 //数据结构 //数据结构是计算机存储、组织数据的方式(规则) //数据结构是指相互之间存在一种或多种特定关系的数据元素的集合 //比如自定义的一个 类 也可以称为一种数据结构 自己定义的数据组合规则 //不要把数据结构想的太复杂 //简单点理解,就是人定义的 存储数据 和 表示数据之间关系 的规则而已 //常用的数据结构(前辈总结和制定的一些经典规则) //数组、栈、队列、链表、树、图、堆、散列表 #endregion #region 知识点二 线性表 //线性表是一种数据结构,是由n个具有相同特性的数据元素的有限序列 //比如数组、ArrayList、Stack、Queue、链表等等 #endregion //顺序存储和链式存储 是数据结构中两种 存储结构 #region 知识点三 顺序存储 //数组、Stack、Queue、List、ArrayList —— 顺序存储 //只是 数组、Stack、Queue的 组织规则不同而已 //顺序存储: //用一组地址连续的存储单元依次存储线性表的各个数据元素 #endregion #region 知识点四 链式存储 //单向链表、双向链表、循环链表 —— 链式存储 //链式存储(链接存储): //用一组任意的存储单元存储线性表中的各个数据元素 #endregion
- LinkedList
#region 知识点一 LinkedList //LinkedList是一个C#为我们封装好的类 //它的本质是一个可变类型的泛型双向链表 #endregion #region 知识点二 申明 //需要引用命名空间 //using System.Collections.Generic LinkedList<int> linkedList = new LinkedList<int>(); LinkedList<string> linkedList2 = new LinkedList<string>(); //链表对象 需要掌握两个类 //一个是链表本身 一个是链表节点类LinkedListNode #endregion #region 知识点三 增删查改 #region 增 //1.在链表尾部添加元素 linkedList.AddLast(10); //2.在链表头部添加元素 linkedList.AddFirst(20); //3.在某一个节点之后添加一个节点 // 要指定节点 先得得到一个节点 LinkedListNode<int> n = linkedList.Find(20); linkedList.AddAfter(n, 15); //4.在某一个节点之前添加一个节点 // 要指定节点 先得得到一个节点 linkedList.AddBefore(n, 11); #endregion #region 删 //1.移除头节点 linkedList.RemoveFirst(); //2.移除尾节点 linkedList.RemoveLast(); //3.移除指定节点 // 无法通过位置直接移除 linkedList.Remove(20); //4.清空 linkedList.Clear(); linkedList.AddLast(1); linkedList.AddLast(2); linkedList.AddLast(3); linkedList.AddLast(4); #endregion #region 查 //1.头节点 LinkedListNode<int> first = linkedList.First; //2.尾节点 LinkedListNode<int> last = linkedList.Last; //3.找到指定值的节点 // 无法直接通过下标获取中间元素 // 只有遍历查找指定位置元素 LinkedListNode<int> node = linkedList.Find(3); Console.WriteLine(node.Value); node = linkedList.Find(5); //4.判断是否存在 if( linkedList.Contains(1) ) { Console.WriteLine("链表中存在1"); } #endregion #region 改 //要先得再改 得到节点 再改变其中的值 Console.WriteLine(linkedList.First.Value); linkedList.First.Value = 10; Console.WriteLine(linkedList.First.Value); #endregion #endregion #region 知识点四 遍历 //1.foreach遍历 foreach (int item in linkedList) { Console.WriteLine(item); } //2.通过节点遍历 // 从头到尾 Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&&&&&&"); LinkedListNode<int> nowNode = linkedList.First; while (nowNode != null) { Console.WriteLine(nowNode.Value); nowNode = nowNode.Next; } // 从尾到头 Console.WriteLine("&&&&&&&&&&&&&&&&&&&&&&&&&&&"); nowNode = linkedList.Last; while (nowNode != null) { Console.WriteLine(nowNode.Value); nowNode = nowNode.Previous; } #endregion
- 泛型栈和泛型队列
#region 知识点一 回顾数据容器 #region 变量 //无符号 //byte ushort uint ulong //有符号 //sbyte short int long //浮点数 //float double decimal //特殊 //char bool string #endregion #region 复杂数据容器 //枚举 enum //结构体 struct //数组(一维、二维、交错) [] [,] [][] //类 #endregion #region 数据集合 //using System.Collections; //ArrayList object数据列表 //Stack 栈 先进后出 //Queue 队列 先进先出 //Hashtable 哈希表 键值对 #endregion #region 泛型数据集合 //using System.Collections.Generic; //List 列表 泛型列表 //Dictionary 字典 泛型哈希表 //LinkedList 双向链表 //Statck 泛型栈 //Queue 泛型队列 #endregion #endregion #region 知识点二 泛型栈和队列 //命名空间:using System.Collections.Generic; //使用上 和之前的Stack和Queue一模一样 Stack<int> stack = new Stack<int>(); Queue<object> queue = new Queue<object>(); #endregion
- 事件
事件不能在类外部赋值,但是可以+=、-=
- 匿名函数
- lambda表达式
using System; namespace Lesson15_lambad表达式 { class Program { static void Main(string[] args) { Console.WriteLine("lambad表达式"); #region 知识点一 什么是lambad表达式 //可以将lambad表达式 理解为匿名函数的简写 //它除了写法不同外 //使用上和匿名函数一模一样 //都是和委托或者事件 配合使用的 #endregion #region 知识点二 lambad表达式语法 //匿名函数 //delegate (参数列表) //{ //}; //lambad表达式 //(参数列表) => //{ // //函数体 //}; #endregion #region 知识点三 使用 //1.无参无返回 Action a = () => { Console.WriteLine("无参无返回值的lambad表达式"); }; a(); //2.有参 Action<int> a2 = (int value) => { Console.WriteLine("有参数Lambad表达式{0}", value); }; a2(100); //3.甚至参数类型都可以省略 参数类型和委托或事件容器一致 Action<int> a3 = (value) => { Console.WriteLine("省略参数类型的写法{0}", value); }; a3(200); //4.有返回值 Func<string, int> a4 = (value) => { Console.WriteLine("有返回值有参数的那么大表达式{0}", value); return 1; }; Console.WriteLine(a4("123123")); //其它传参使用等和匿名函数一样 //缺点也是和匿名函数一样的 #endregion Test t = new Test(); t.DoSomthing(); } } #region 知识点四 闭包 //内层的函数可以引用包含在它外层的函数的变量 //即使外层函数的执行已经终止 //注意: //该变量提供的值并非变量创建时的值,而是在父函数范围内的最终值。 class Test { public event Action action; public Test() { int value = 10; //这里就形成了闭包 //因为 当构造函数执行完毕时 其中申明的临时变量value的声明周期被改变了 action = () => { Console.WriteLine(value); }; for (int i = 0; i < 10; i++) { //此index 非彼index int index = i; action += () => { Console.WriteLine(index); }; } } public void DoSomthing() { action(); } } #endregion //总结 //匿名函数的特殊写法 就是 lambad表达式 //固定写法 就是 (参数列表)=>{} //参数列表 可以直接省略参数类型 //主要在 委托传递和存储时 为了方便可以直接使用匿名函数或者lambad表达式 //缺点:无法指定移除 }
- List排序
自定义List中的sort排序
class Moster { public int Hp; public int Attack; public int Defense; public Moster(int hp, int atk, int def) { this.Hp = hp; this.Attack = atk; this.Defense = def; } } class SortTest { static void Main(string[] args) { List<Moster> mosters = new List<Moster>(); mosters.Add(new Moster(100, 20, 110)); mosters.Add(new Moster(200, 60, 105)); mosters.Add(new Moster(1400, 20, 130)); mosters.Add(new Moster(140, 26, 110)); mosters.Add(new Moster(160, 22, 155)); //Sort重载,传入匿名函数进行自定义函数排序 mosters.Sort((a, b) => { return (a.Attack > b.Attack) ? 1 : -1; }); foreach (var monster in mosters) { Console.WriteLine(monster.Attack); } } }
反转List中的元素
List.Reverse();
- 协变 逆变
- Thread
class Program { static object obj = new object(); static void Main(string[] args) { Thread t = new Thread(Test); //设置为后台线程,随主线程结束而结束 t.IsBackground = true; //调用多线程 t.Start(); //主线程休眠 Thread.Sleep(5000); //中止线程 // t.Abort(); // t = null; } static void Test() { //给线程加锁,仅在obj未被其他线程锁住时才能接入锁住的代码块 lock (obj) { //在线程调用的方法内执行sleep休眠此线程 Thread.Sleep(3000); Console.WriteLine("多线程测试"); } } }
- 反射
- 特性
- 迭代器
- 特殊语法
本文作者:Nyanyan
本文链接:https://www.cnblogs.com/nyan/p/17668835.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步