网站建设方法,营销型网站建设818gx,页面seo是什么意思,建设网站公司兴田德润i优惠吗目录
数据结构
集合
动态数组ArrayList
习题#xff1a;声明一个Monster类#xff0c;有一个Attack方法,用一个ArrayList去封装Monster的对象,装10个#xff0c;遍历monster的list让他们释放攻击方法
哈希表HashTable
创建一个武器类#xff0c;有一个属性叫做id,每个…目录
数据结构
集合
动态数组ArrayList
习题声明一个Monster类有一个Attack方法,用一个ArrayList去封装Monster的对象,装10个遍历monster的list让他们释放攻击方法
哈希表HashTable
创建一个武器类有一个属性叫做id,每个武器对象的id不一样创建10把武器把这10把武器通过id存储在哈希表中可以通过id在哈希表中找到对应的武器
栈Stack
栈在游戏开发中的应用
队列Queue
游戏开发中的应用
泛型
手动输入一组数列可任意长度并对这个数列进行排序每次提示用户输入1、添加一个数字2、排序并显示数列
书写一个怪物Monster类在怪物类的构造中将其添加到一个静态列表以怪物类做为基类派生Boss和Gablin的对象产生不用的攻击行为多态可以写一个方法让怪物按攻击力进行排序从小到大。
字典
书写一个方法可以把输入的数字转换成中文数字
委托
老师们会在下课时打铃事件 学生们想在打铃事件发生的时候做自己的事情小明想在打铃的时候去买东西吃小张想在打铃时去打水小红想在打铃时去打羽毛球
事件
观察者模式
匿名委托与Lambda表达式
有一个int类型的List,升序排序和降序排序不能使用List的Sort方法只能自己写一个排序的方法通过委托传递方法变量去改变排序的逻辑
匿名方法
Lambda表达式 匿名方法的升级
泛型委托
Action的演示
Func的演示 数据结构
描述数据之间的关系
行为添加数据、删除数据、插入数据、查找数据
追加数据向结构的末尾添加一个数据
删除数据向结构中删除指定的数据
插入数据向结构中某位置插入指定的数据
查找数据可以查找并访问到该数据
修改数据对该结构指定的数据进行重新赋值
线性、链式、树状、图形、散列
链式是非连续的内存空间是每个数据分成三部分
头、数据、尾每个数据的尾部连接下一个数据的头部
所以在内存不是连续的空间而是一个一个的空间通过头尾地址连接在一起 集合 Collection是C#写好的数据结构类库
ArrayList、HashTable、Stack、Queue
如果你是用这些数据结构类的模板要先引用System.Collections;
就可以通过类名去实例化它的对象
动态数组ArrayList 是封装过后的数组里面的元素容器为Object类型 这样ArrayList就适用于所有的数据类型 因为Object类型是所有类的父类又因为里氏转化原则父类可以装载子类所以ArrayList可以装载所有数据类型 属性 Count记录当前拥有多少个元素 Capacity记录当前可以包含多少元素 方法 添加.Add(Object value) 把当前这个对象添加到数组中 删除 .Remove(Object value) 查询此元素并移除第一个匹配的元素项 .RemoveAtint index 根据下标号移除该元素 插入 .Insertint index ,Object value 把对应对象插入到对应的下标 访问/修改:通过索引器下标号 排序Sort(); 反转Reverse(); 检测是否包含Contains(Object value) 检测该集合是否包含改元素如果包含返回true不包含返回false 查找索引.IndexOfObject value 找到第一个匹配该元素的下标号并返回 如果没找到则返回-1 习题声明一个Monster类有一个Attack方法,用一个ArrayList去封装Monster的对象,装10个遍历monster的list让他们释放攻击方法 internal class Monster{public string name;public Monster(string name){this.name name;}public void Attack(){Console.WriteLine({0}攻击了, name);}}static void Main(string[] args){ArrayList monsterListnew ArrayList();for(int i0;i10;i){monsterList.Add(new Monster(第i号哥布林));}for (int i 0; i monsterList.Count; i){if(monsterList[i] is Monster){(monsterList[i] as Monster).Attack();//ArrayList装载的是Object类型,需要里氏转换原则}}} 哈希表HashTable 也是System.Collections集合下的数据结构类 它储存的也是object类型的对象,但是它在内存中是散列排布的 因为这个特性非常适合存储大量的数据 在HashTable中一个键只能对应一个值一个值可以对应多个键多对一的关系 HashTable存储的是键,值对 HashTable tablenew HashTable(); 属性 Count:HashTable包含的键值对的数目 KeysHashTable中键的集合 ValuesHashTable中值的集合 方法 增删改查 Add(key,value)在哈希表中添加一对键值对 Removekey删除键值 因为一个值有可能对应多个键这样就不能把整个键值对删除掉 只要没有键指向这个值就会自动被释放掉所以只需要删除键值就可以了 Containskey检测是否包含此键值对 ContainsKeykey检测是否包含此键 ContainsValuevalue检测是否包含这个值 访问索引器[键] 在内存中散乱排布用foreach去遍历键 foreachvar key in table.keys { Console.WriteLine(hashtable[key]); } 创建一个武器类有一个属性叫做id,每个武器对象的id不一样创建10把武器把这10把武器通过id存储在哈希表中可以通过id在哈希表中找到对应的武器
static void Main(string[] args){Hashtable tablenew Hashtable();//假设有一把武器叫霜之哀伤id为123//并把霜之哀伤放进我的武器目录里Weapon a new Weapon(霜之哀伤);table.Add(123,a);table.Add(456,a);Console.WriteLine(table[456]);}internal class Weapon{public string name;public Weapon(string name){this.name name;}public override string ToString(){return name;}} 栈Stack 也是System.Collections下的数据结构类存储的依然是Object 类型的对象 Stack stacknew Stack(); Count:实际拥有的元素个数 栈的释放顺序是先进后出 压栈——Push(Object 对象)把这个对象添加到栈的顶部 弹栈——Pop()把栈顶的元素弹出来,会删除 Peek() 返回栈顶的元素不删除 在遍历弹栈的时候要注意pop方法会删除你的对象导致Count属性发生改变 所以应该用一个变量存储一下一开始的Count值根据这个变量来弹栈就可以把栈中所有的数据弹出去 Stack stack new Stack(); for(int i0;i10;i) { stack.Push(i); } int static_Countstack.Count; for(int i0;istatic_Count;i) { Console.WriteLine(stack.Pop()); } 栈在游戏开发中的应用 用来实现”返回/撤销”功能。可以将每一步的操作或者是坐标信息加入到stack中当玩家按下返回/撤销键时将上一步操作从栈中移除并根据其中的信息在游戏中反向操作 常常被用到在游戏”状态/窗口/场景”管理中。在游戏中往往会有多个窗口叠加在一起或者从一个场景进入到子场景。这时通过在进入“新场景/打开新窗口”时将这个”场景/窗口”加入到stack中玩家选择返回时再从栈中弹出并销毁所有的事件和操作都只对当前的顶端的窗口生效 队列Queue 是System.Collections下的数据结构类存储Object类型的对象 Queue queuenew Queue(); 队列的释放顺序先进后出 属性 Count:该结构包含的元素个数 方法 EnQueueObject value进入队列的末尾处 DeQueue() 返回并移除队列最前面的那个元素 Peek() 队列中队首的元素返回但不删除 游戏开发中的应用 回合制游戏中的行动顺序队列Turn Queue 回合制和半回合制游戏中常常有速度、行动力的概念来决定场上所有单位的行动顺序这个时候可以通过队列来安排。当然很多游戏中会有提升或降低速度的技能和物品这个时候会需要重新生成队列。 管理经营类游戏中的生产队列 很多管理经营类游戏或者即时战略游戏中都会有生产队列的概念。通过使用队列来提前规划之后的生产顺序可以使玩家操作起来更为方便。一个典型的例子就是文明系列中在城市里的生产列队提前安排之后需要生成的单位或设施将后续需要制造的东西依次加入队列当当前生产任务完成时从队列中移除并获取下一个需要生成的单位。 行动队列 很多及时战略游戏和MOBA类游戏中都有用队列提前安排之后的行动的功能。例如DotA中可以在TP的时候按住Shift将跳刀加到行动队列中实现落地瞬间跳走沙王施法前摇时将跳到放到队列中实现跳大等操作。 剧情对话 当剧情对话会因为玩家的选择产生分支的时候常常需要用树结构来储存但归根结底这可以被当作一种非线性的队列。实际运行的时候还是可以用Queue来储存和操作正在播放的剧情文字分支产生并被选择以后再将该分支下的对话加入到队列中。 动画播放多节点移动 游戏动画中有时候会有沿着一系列节点移动的操作这个过程可以使用队列来完成将所有节点按照顺序加入队列然后用dequeue获取并移除队列顶端的点来实现按照相同顺序移动。 消息、事件的传输和分发 一些网游或者多进程的单机需要用接收、处理从网络或其他进程传入的指令和消息而当本地在处理消息的时候其他陆续传入的消息将在队列中等待然后当前一个任务执行完毕后从队列中获取下一个需要被执行的指令或需要处理的消息。 泛型
因为在编程中想先不定义数据类型只想先写逻辑可以使用Object类型这样逻辑就适用于所有类型但是在运行中Object类型的变量会需要转换到对应类型浪费资源所以出现泛型代替Object类型的方案
使用泛型可以延迟定义数据类型来编写程序
泛型是一种将逻辑应用到不同数据类型上的机制可以通过类型代替符来暂时代参数的数据类型这样只需要在编译的时候编译器会自动将替代符编译成对应数据类型来处理 泛型方法 定义泛型方法 访问修饰符 返回类型 方法名T,UT 参数U参数{} 可以在方法名后使用类型替代符来定义一个泛型方法 手动输入一组数列可任意长度并对这个数列进行排序每次提示用户输入1、添加一个数字2、排序并显示数列
static void Main(string[] args){Listint list new Listint();list.Add(1); list.Add(4);list.Add(8);list.Add(2);list.Add(3);list.Add(9);list.Add(5);list.Add(6);list.Add(7);list.Add(10);Console.WriteLine(提示用户输入1可添加一个数字;如果用户输入2排序并显示此数列);int aint.Parse(Console.ReadLine());if(a1){list.Add(a);}if(a2){list.Sort();for(int i0;ilist.Count;i){Console.WriteLine(list[i]);}}}
书写一个怪物Monster类在怪物类的构造中将其添加到一个静态列表以怪物类做为基类派生Boss和Gablin的对象产生不用的攻击行为多态可以写一个方法让怪物按攻击力进行排序从小到大。 static void Main(string[] args) { for(int i 0; i 10; i) { new Goblin(第 i 号哥布林); } new Boss(拉格拉罗斯); //Console.WriteLine(MonsterManager.monsterList[1]); for (int i 0; i MonsterManager.monsterList.Count; i) { MonsterManager.monsterList[i].Attack(); } } internal class MonsterManager { public static ListMonster monsterList new ListMonster(); public static Random rnew Random(); } class Monster { public string name; public int attack; public Monster (string name) { this.name name; MonsterManager.monsterList.Add(this); } public virtual void Attack() { } public override string ToString() { return String.Format({0}/攻击力,{i},name,attack); } } class Goblin : Monster { public Goblin(string name) : base(name) //先去执行base指向的public Monster (string name) //已经把name的赋值了再执行自己的攻击 { attack MonsterManager.r.Next(50,100); } //用overrider关键字重写Attack()方法 public override void Attack() { Console.WriteLine({0}丢了一块石头砸人特别疼,name); } } class Boss:Monster { public Boss(string name):base(name) { attackMonsterManager.r.Next(200,500); } public override void Attack() { Console.WriteLine({0}一口炎爆术喷了出来特别吓人, name); } } 字典 书写一个方法可以把输入的数字转换成中文数字
把123转换为壹贰参. Dictionarychar,char
思路建立一个0-9的字典作为key存储对应value壹贰参输入参数作为键在字典里查找再把值保存下来 internal class Program { static void Main(string[] args) { Console.WriteLine(请输入一个数字); string inputConsole.ReadLine(); UpperNum(input); } public static void UpperNum(string input) { Dictionarystring , string dic new Dictionarystring, string(); dic.Add(1, 壹); dic.Add(2, 贰); dic[3] 叁; dic[4] 肆; dic.Add(5, 伍); dic.Add(6, 陆); dic[7] 柒; dic[8] 捌; dic[9] 镹; dic[0] 零; string result ; for(int i 0; i input.Length; i) { result resultdic[input[i].ToString()]; } Console.WriteLine(result); } } 委托 是方法的载体引用可以承载一个或多个方法 是一种特殊数据类型专门用来存储方法 所有的委托都派生自System.Delegate类 委托可以让我们把方法当作变量去使用 解决了很多代码冗余的问题也解决了方法回调的问题 委托的定义 访问修饰符delegate返回类型 委托类型名参数列表 委托的变量 委托类型名 委托变量名 委托类型名 委托变量名new 委托类型返回类型与参数列表一致方法 委托的赋值 在装载方法的时候不用写小括号 委托变量名返回类型与参数列表一致方法 委托的调用 委托变量名参数 委托变量名.Invoke参数; 列表的查找速度比链表要快 链表的修改速度要比列表快 回调 把委托变量传入方法中去调用 委托的本质 就是方法引用的队列先进先出一旦调用会把队列中所有的方法执行完 委托的注册 委托名方法名 就可以将多个方法注册进委托变量中 委托的注销 委托名-方法名 可以将方法从委托列表中移除 委托变量一旦重新赋值以前引用的方法全部丢失 可以使用委托变量null全部清空方法列表 老师们会在下课时打铃事件 学生们想在打铃事件发生的时候做自己的事情小明想在打铃的时候去买东西吃小张想在打铃时去打水小红想在打铃时去打羽毛球 static void Main(string[] args) { Teacher t new Teacher(王老师); Student xiaoming new Student(小明, 买东西吃); Student xiaohua new Student(小花, 打羽毛球); t.RegisterCallEvent(xiaoming.DoThing); t.RegisterCallEvent(xiaohua.DoThing); t.Call(); } delegate void CallDelegate(); internal class Teacher { public string name; CallDelegate callDel; public void RegisterCallEvent(CallDelegate del) { callDel del; } public void LogoutCallEvent(CallDelegate del) { callDel - del; } public Teacher(string name) { this.name name; } public void Call() { Console.WriteLine({0}打铃了, name); if(callDel ! null) { callDel(); } } } internal class Student { public string name; public string thing; public Student(string name,string thing) { this.name name; this.thing thing; } public void DoThing() { Console.WriteLine(namething); } } 事件
委托变量如果公开出去很不安全外部可以随意调用
所以取消public封装它可以自己书写两个方法供外部注册与注销委托调用在子方法里调用这样封装委托变量可以使它更安全这个叫做事件。 特性 外部不能随意调用只能注册和注销只能自己去调用自己的委托 C#为了方便封装委托变量推出一个特性event事件在委托变量前用event修饰这个变量这个委托变量就变成了事件这样的话这个委托变量就算公开出去也没有关系因为外部只能对这个变量进行注册和注销只能内部进行触发。
观察者模式 模式——视图 发布——订阅 源——收听者 一系列对象来监听另一个对象的行为被监听者一旦触发事件/发布消息则被所有监听者收到然后执行自己的行为 就是使用委托/事件让一系列对象把它们的行为来注册到我们的委托中 一群对象在观察另外一个对象的行为当这个对象的行为达成一定条件则触发了一群对象的反应要做到以上功能要搭配事件使用 把一群对象的反应行为注册到被观察的对象的事件中去 匿名委托与Lambda表达式
有一个int类型的List,升序排序和降序排序不能使用List的Sort方法只能自己写一个排序的方法通过委托传递方法变量去改变排序的逻辑 delegate bool SortDel(int a,int b); internal class Program { static void Main(string[] args) { Listint list new Listint(); Random r new Random(); for(int i 0; i 10; i) { list.Add(r.Next(1,1000)); } //匿名方法Sort(list,delegate(int a,int b) { return ab;}); Sort(list, (a, b) a b);//lambad表达式 for(int i 0; i list.Count; i) { Console.WriteLine(list[i]); } } public static void Sort(Listint list,SortDel del) { for(int i0; i list.Count; i) { for(int j0; j list.Count-1-i; j) { if (del(list[j],list[j1])) { int templist[j]; list[j]list[j1]; list[j1]temp; } } } } } 匿名方法
和委托搭配使用方便我们快速对委托进行传参【作用】
不需要我们去定义一个新的函数
直接用delegate关键字代替方法名后面跟上参数列表与方法体
Delegate参数列表{方法体}
Lambda表达式 匿名方法的升级
更加简写
参数列表{方法体}
当你的方法体只有一条语句的时候可以不写return甚至可以没有花括号
参数列表的参数甚至可以不写数据类型
如果说方法体里一旦出现了return一定要加上花括号
泛型委托
自定义泛型委托
delegate T 委托名TT 参数;
C# 提供好了两个泛型委托的模板供我们使用
这两个模板基本上就可以适用于所有的委托
所以其实是不需要我们自定义的
不带返回类型的泛型委托——Action类型1类型2……类型n参数列表对应的参数类型带返回类型的泛型委托——Func类型1类型2……类型n参数列表的末尾类型是作为返回类型使用
Action的演示 static void Main(string[] args) { Test(100, ActionEvent); } public static void ActionEvent(int a) { Console.WriteLine(a); } public static void Test(int num,Actionint del) { del(num); } Func的演示 static void Main(string[] args) { Listint list new Listint(); Random r new Random(); for(int i0;i10;i) { list.Add(r.Next(1,100)); } Sort(list,delegate(int a,int b) { return ab;}); for(int i0;ilist.Count;i) { Console.WriteLine(list[i]); } } public static void Sort(Listint list,Funcint,int,bool func) { for(int i0;ilist.Count;i) { for(int j0;jlist.Count-i-1;j) { if(func(list[j],list[j1])) { int templist[j]; list[j]list[j1]; list[j1]temp; } } } }