泛型<T>
使用泛型能够最大限度的重用代码/保护类型安全,提高性能
泛型成员因为类型的不确定性,不能使用算术运算符/比较运算符
类型参数可以有多个,可以是编译器能够识别的任何类型
类型参数的名字不能随便起,不能重名
//使用泛型 //数组类Array //泛型类-需要在类名前加上泛型类型 //定义的时候需要用T泛型类型表示任意一种数据类型 //T-Type,S/U/V 表示其他类型 //K/V-key/value public class Array<T,S,U,V> { //索引器 public T this[int index] { set { _arr[index] = value; } get { return _arr[index]; } } public int Count { get { return _count; } } public void Log() { string str = "当前数组中包含" + Count + "个元素 ("; for (int i = 0; i < Count; i++) { str += _arr[i]; if (i < Count - 1) { str += ", "; } } str += ")"; Console.WriteLine(str); Console.ReadLine(); } public void Add(T value) { _arr[_count] = value; _count++; } public Array() { _arr = new T[100]; } private T[] _arr; private int _count = 0; } static void Main(string[] args) { //当具体需要使用的时候才需要确定实际的类型,可以将int改为其他类型 Array<int> arr = new Array<int>(); arr.Log(); arr.Add(2); arr.Log(); arr.Add(34); arr.Log(); }
ArrayList
arraylist 属于一种集合
集合是种容器,在程序中,使用集合管理相关对象组,集合分为非泛型集合和泛型集合
ArrayList是一个特殊的数组,通过添加或者删除元素就可以动态改变数组长度
可以灵活地插入/删除,访问元素,不是强类型,速度跟普通的数组比要慢。ArrayList存入的数据类型系统会默认为Object类型,因此接收元素需要强制转换。
public static void Log(ArrayList arr) { string str = "当前数组中包含" + arr.Count + "个元素 ("; for (int i = 0; i < arr.Count; i++) { str += arr[i]; if (i < arr.Count - 1) { str += ", "; } } str += ")"; Console.WriteLine(str); Console.ReadLine(); } public static void Main(string[] args) { //首先创建对象 ArrayList arr = new ArrayList(); Log(arr); //使用Add()方法添加元素,对元素类型没有限制 arr.Add(17); arr.Add(4.5f); arr.Add("xiaoli"); Log(arr); //使用下标获取指定位置的元素 //获取当前数组中元素的数量 int count = arr.Count; //使用insert方法向指定下标位置插入元素 arr.Insert(1, "hello"); Log(arr); //使用Remove方法从数组中删除指定元素 arr.Remove(4.5f); Log(arr); //RemoveAt方法将指定下标位置删除 arr.RemoveAt(0); Log(arr); //是否存在指定元素 Console.WriteLine(arr.Contains("hello")); //清空整个数组 arr.Clear(); Log(arr); }
List
List属于泛型集合,是一种强类型列表,其方法的使用与ArrayList相似。更推荐使用List类型,因为更安全。
声明一个List对象:List<string> arr=new List<string>();//List 对元素类型有限制,一旦确定为某类型,就必须是某类型
字典
Dictionary是存储键和值的集合,属于泛型集合,使用时需引入泛型集合命名空间
Dictionary是无序的,键Key是唯一的
public static void Main(string[] args) { //创建一个字典对象,key的类型是string,value的类型是int Dictionary<string, int> dic = new Dictionary<string, int>(); //Add方法用来添加键值对 dic.Add("laowang", 13); dic.Add("hello", 15); //删除键值对 dic.Remove("hello"); //清空 dic.Clear(); //获取当前字典中Key,value的个数 int count = dic.Count; Console.WriteLine(count); //检查字典中是否包含指定的key bool b = dic.ContainsKey("xiaoming"); //检查字典中是否包含指定的value bool c = dic.ContainsValue(13); //尝试获取指定的key所对应的value int s; bool bb = dic.TryGetValue("xiaoming", out s); //如果当前包含“xiaoming”这个key,则获取对应的value并保存在s中,bb=true //如果当前不包含“xiaomign”这个key,则s=null,bb=false //通过Key获取value int age = dic["laowang"]; Console.WriteLine(age); Console.ReadLine(); }
栈<stack>与队列<Queue>
属于泛型集合。栈遵循后进先出原则
队列遵循先进先出原则栈与队列根据需要容量自动添加
栈与队列都允许重复元素
public static void Main(string[] args) { //栈 Stack<string> s = new Stack<string>(); int count = s.Count; s.Clear(); bool a = s.Contains("xiao"); //将元素放入栈,使用Push方法 s.Push("xiaomign"); s.Push("helllo"); s.Push("tian"); //使用Pop方法把元素出栈,后进先出 //队列 先进先出 Queue<string> q = new Queue<string>(); q.Clear(); int cou = q.Count; bool d = q.Contains("xiaomign"); //添加元素 q.Enqueue("xiaomign"); q.Enqueue("haha"); q.Enqueue("lala"); //取出元素 string s1 = q.Dequeue(); Console.WriteLine(s1);//输出xiaoming Console.ReadLine(); }
委托
委托是一种特殊的类型,用于引用方法
定义委托需要用delegate关键字
委托可以把方法当作参数来传递
委托可以使用+-运算符合并/解绑委托
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace test2 { class Program { //定义委托-访问修饰符 delegate 返回值类型 委托名(参数列表); public delegate void Something(string name); public class Student { //可以像普通类型一样当作方法参数传递 public void Do(Something something) { //可以像普通方法一样调用 //真正调用了方法A--方法回掉 something(name); } public Student(string name) { this.name = name; } private string name; } public class Teacher { public void Hungry() { Student s = new Student("laowang"); //创建委托变量 Something a = new Something(A); Something b= new Something(B); s.Do(a+b);//委托对象可以使用+,-来绑定解除委托 } public void A(string name) { Console.WriteLine("hello"+name); Console.ReadLine(); } public void B(string name) { Console.WriteLine("你好" + name); Console.ReadLine(); } } public static void Main(string[] args) { Teacher t = new Teacher(); t.Hungry(); } } }
事件
event和delegate的关系就好像是字段和属性的关系
event会限制delegate不能够直接赋值操作,防止将委托替换掉,只能使用+=和-=来绑定或解除委托
event还限定了delegate只能在定义的类中被调用
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; namespace test2 { class Program { public delegate void Something(string name); public class Student { //event就是delegate的“属性” public event Something something; public void Do() { something(name); } public Student(string name) { this.name = name; } private string name; } public class Teacher { public void Hungry() { Student s = new Student("laowang"); //使用事件后不能够直接赋值操作,防止将委托替换掉,只能使用+=和-=来绑定或解除委托 s.something += new Something(A); //使用事件后不能在Student外界调用委托-s.something("hello"); s.Do(); } public void A(string name) { Console.WriteLine("hello"+name); Console.ReadLine(); } } public static void Main(string[] args) { Teacher t = new Teacher(); t.Hungry(); } } }