//用百度的文言一心得到的
泛型是一种编程语言的特性,它可以在类型之间进行通用的数据传递和操作,从而使代码的设计更加灵活和方便。泛型主要包括以下几个方面的知识点:
泛型类、泛型接口、泛型方法、泛型委托等概念:这些概念是泛型编程中的基础,需要理解它们的定义、实现和应用场景。
泛型约束:泛型类型之间的依赖关系可以用泛型约束来表示,它可以帮助程序员更好地控制泛型类型之间的依赖关系。
协变、逆变:泛型编程中经常需要对参数进行协变和逆变操作,以适应不同的数据类型和操作方式。
泛型缓存:泛型编程中经常需要对数据进行缓存,以提高程序的性能和并发性。
泛型应用场景:泛型的应用场景非常广泛,包括自动化测试、数据库连接、网络通信等等。
//语法糖???
//泛型:简单理解就是宽泛的不确定的一种类型
//也就是带尖括号,在使用的时候,可以随便的给他指定一个类型
//在想每个类型都要一一传递调用,而object类型直接搞定,object类型是一切类型的父类
//难道所有的类型都用object传递调用?
//那性能问题,性能安全呢?
//import!!!装箱和拆箱?
//值类型存放在栈里面,而object要传递引用类型进来(堆)。
//那么就需要把值类型转化为引用类型,再去调用object//装箱
//需要得到值类型,再从object里面引用类型那,在转化为值类型,在拿来用//拆箱
//现在就要考虑泛型了
//泛型的一个设计思想
//想一个问题泛型在计算机最后执行的时候,能够确定是什么类型吗,
//其实在进行编译后,已经可以确定是某种类型了。
//声明的时候有一个占位符,不确定它的类型
//运行的时候一定要确定类型,也就是延迟声明
//:T类型参数,占位符,没有明确的类型
//传递进来的方法的参数类型
那么就需要把值类型转化为引用类型,再去调用object//装箱
需要得到值类型,再从object里面引用类型那,在转化为值类型,在拿来用//拆箱
//一个类可以满足不同类型的需求
//在运行之前更具不同的类型生成各自的副本
//再类声明的时候,带有尖括号给定一个类型参数
public class Abs
{
}
internal class Program
{
static void Main(string[] args)
{
//三种调用以后,会生成三个类型
Abs a = new Abs();
Abs b = new Abs();
Abs
//import!!!泛型方法:
//一个方法可以支持不同类型的参数
//调用的时候指定类型
//指定的类型必须和参数类型一致
//在调用的时候,如果可以更具参数推导出类型的话,尖括号中的类型声明可以不写
public static void Show(T prarams){
Console.WriteLine($"{prarams}");
}
}
internal class Program
{
static void Main(string[] args)
{
int a = 1;
Commend.Show(a);
Commend.Show(a);
//定义:泛型约束指的就是声明泛型的时候指定一些约束条件,那么在使用的时候会自行进行约束条件的判断
//1
where T:struct//指定的类型必须是值类型
class Test01 where T:struct{}
//值类型约束,需要值类型
new Test01();
//2
where T:class//指定类型必须是引用类型
class Test02 where T:class{}
//引用类型约束
new Test02();
//3
where T:new()//指定类型必须有无参数的构造函数
class Test03 where T:new(){}
//如果是有参数会怎么样?
new Test03();
//4
where T:类名/接口名//指定类型必须是类,接口或类,接口的子类
class Test04 where T:GameObjec{}
public class GameObjec{}
public class Cube:GameObjec{}
new Test04();
new Test04();
//5
class Test05 where T:Ienumerable{}
new Test05();
new Test05();
//6
where T:泛型//指定类型必须是约束泛型或约束泛型的子类型
class Test06 where T:K{}
new Test06();
new Test06();
//定义协变out和逆变in是在接口和委托中用于修饰泛型的,主要用于定义泛型类型的使用区域
//语法: T的泛型类型只能用于返回值类型, T的泛型类型只能用于参数列表类型。
//接口中使用
interface I_out{
//协变只能是返回值类型
T move();
void Run(T speed)//?报错吗?当成什么了?参数列表?返回值?
}
interface I_in{
T move();//报错?这是当成什么了?参数列表?返回值?
//逆变只能是参数列表
void Run(T speed);
}
//委托中使用
delegate R CustomDelegate(V v,E e);//怎么理解呢?
//两个逆变参数参数,一个协变参数 返回值R
public static string Answer(string s,char a){
return s+a;
}
CustomDelegate str=end;//存储
Console.WriteLine(str("c#",'$'));
ArrayList是系统提供的一个集合容器,主要用于存储数据。这样就想到前面的数组容器,为什么还要用ArrayList?其实数组容器是一个连续空间的固定大小的一个容器。这样的特点也就让数组容器比较利于查询和修改,但是添加和删除就会导致容器大小的变化,然后呢就需要重新进行数组的创建很难受。那么ArrayList就将这些复杂的操作进行封装,我们只需要调用就可以了。
内容分为:增删改查
特点:底层采用object[]实现,可以存储任何数据类型,可以存储重复元素
//创建一个空容器,以便下面进行增删改查操作
ArrayList arrayList = new ArrayList();
//进行增操作
arrayList.Add("A");
//Console.WriteLine(arrayList[0]);
//在创建一个空容器进行一个范围增操作
ArrayList arrayList1 = new ArrayList();
arrayList1.Add("B");
arrayList1.Add("C");
arrayList1.Add("D");
arrayList.AddRange(arrayList1);//范围增操作
NewMethod(arrayList);
//想要在指定位置增加
//1,A,B,C,D,
arrayList.Insert(0, "1");
NewMethod(arrayList);
//查操作
Console.WriteLine(arrayList.Capacity);//8容器大小
Console.WriteLine(arrayList.Count);//5元素个数
Console.WriteLine(arrayList[0]);//1
//该操作
//1,2,B,C,D,
arrayList[1] = "2";
NewMethod(arrayList);
//删除操作
//2,B,C,D,
arrayList.Remove("1");
NewMethod(arrayList);
//删除指定元素
//2,C,D,
arrayList.RemoveAt(1);
NewMethod(arrayList);
//清空
//arrayList.Clear();
//Console.WriteLine(arrayList.Count);//查看元素个数//0
//2-C-D-
//遍历
foreach (string item in arrayList)
{
Console.Write(item + "-");
}
//迭代器
IEnumerator enumerator = arrayList.GetEnumerator();
while(enumerator.MoveNext())//推到下一个元素movenext
{
Console.Write($"{enumerator.Current}~");//当前位置的元素current,每推动元素一次movenext,拿到一次元素current
}
Console.ReadKey();
}
///
/// 打印arraylist元素
///
///
private static void NewMethod(ArrayList arrayList)
{
for (int i = 0; i < arrayList.Count; i++)
{ //count:包含的元素
Console.Write($"{arrayList[i]},");
}
Console.WriteLine();
}
}
stack类是c#提供的一个容器类,底层采用object[]数组实现,封装对数组的相关操作。
特点:先进后出,类似于上弹夹原理,储存重复元素
//创建容器对象
Stack stack = new Stack();
//增操作add?
stack.Push("1");
stack.Push("2");
stack.Push("3");
stack.Push("4");
stack.Push("5");
//查看操作
Console.WriteLine(stack.Count);//查看元素个数
//查看栈顶元素//5
Console.WriteLine(stack.Peek());
//删除操作
stack.Pop();//删除顶部的元素
Console.WriteLine(stack.Peek());//4
Console.WriteLine(stack.Count);//4
//遍历
object[] obgs = stack.ToArray();//转化为数组
//从栈顶开始遍历
for (int i = 0; i < obgs.Length; i++)
{
Console.WriteLine(obgs[i]+"-");
}
//通过弹栈的方式遍历:4-1
int num=stack.Count;
for (int i = 0;i
Queue类是c#提供的一个容器类,简称队列,底层采用object[]实现。封装了CRUD方法
特点:先进先出,可以储存重复元素
//创建容器类
Queue queue= new Queue();
//进入队列
queue.Enqueue("a");//Enqueue添加到结尾出
queue.Enqueue("b");
queue.Enqueue("c");
//查看数量
Console.WriteLine(queue.Count);//3
Console.WriteLine(queue.Peek());//查看位于队列最上面的元素
//出队列
queue.Dequeue();//移除最上面的元素
Console.WriteLine(queue.Peek());//b
Console.WriteLine(queue.Count);//2
//判断元素是否在
Console.WriteLine(queue.Contains("c"));//Contains确定元素是否在queue
//循环出队列
//int count=queue.Count;
//for (int i=0; i
Hashtable是c#提供的一个用于存储key-value键值对的容器,底层采用hash表进行存储
特点:存储的键值对,不按顺序存储,不能存储重复数据(key)
//创建空容器
Hashtable hashtable = new Hashtable();
//增操作
hashtable.Add(1, "A");
hashtable.Add(2, "B");
hashtable.Add(3, "C");
//查操作
Console.WriteLine(hashtable.Count);//3
Console.WriteLine(hashtable.ContainsKey(1));//bool//true
Console.WriteLine(hashtable.ContainsValue("A"));//bool//true
//通过key查找value
Console.WriteLine(hashtable[1]);//A
//改操作
hashtable[1] = "D";
Console.WriteLine(hashtable[1]);//D
//删除操作
hashtable.Remove(1);
Console.WriteLine(hashtable.Count);//2
//清空操作
hashtable.Clear();
Console.WriteLine(hashtable.Count);//0
//初始化
hashtable.Add(1, "A");
hashtable.Add(2, "B");
hashtable.Add(3, "C");
//遍历
foreach (int item in hashtable.Keys)//通过keys找值
{
Console.WriteLine($"{item}-{hashtable[item]}");
}
foreach (string item in hashtable.Values)//查找值
{
Console.WriteLine($"{item}");
}
foreach (DictionaryEntry entry in hashtable)//通过hashtable查找
{
Console.WriteLine($"{entry.Key}-{entry.Value}");
}
Console.ReadKey();
可以存储任何类型的数据,反过来说,在取出数据进行逻辑处理的时候非常繁琐,要进行类型判断,类型转化,逻辑处理
如何解决处理数据业务逻辑的繁琐性?本质集合存储的是任何数据类型的数据,然后就想着能不能限制集合容器只能是一种数据类型呢?(泛型集合就出来了)
ArrayList arrayList= new ArrayList();
arrayList.Add(1);
arrayList.Add("D");
arrayList.Add(true);
arrayList.Add(new object());//添加int,string,bool,object
//遍历
foreach (object obj in arrayList)//什么类型呢?只有object合适
{
//类型判断
if (obj is int) {
int ele= (int)obj;
Console.WriteLine($"{ele}-{ele+10}");//1-11
}else if (obj is string) {
string ele= (string)obj;//obj as string
Console.WriteLine($"{ele}-{ele + 10}");//D-D10
}
else if (obj is bool) {
bool ele= (bool)obj;
Console.WriteLine($"{ele}-{!ele}");//True-False
}
else if(obj is object) {
object ele= (object)obj;
Console.WriteLine($"{ele}-{ele.GetType()}");//System.Object-System.Object
}
else
{
Console.WriteLine("不是int,bool,string,object");
}
}
Console.ReadKey();
List
小例子:List
List list = new List();
//增操作
list.Add("a");//[0]-a
list.Insert(1, "b"); //[1]-b
//查操作
Console.WriteLine(list.Count);//2
Console.WriteLine(list[1]);//b
//改操作
list[0] = "D";//[0]-D [1]-b
Console.WriteLine(list[0]);//D
//删除操作
list.RemoveAt(0);
Console.WriteLine(list[0]);//b [0]-b
Console.WriteLine(list.Count);//1
//清空操作
list.Clear();
Console.WriteLine(list.Count);//0
//存储
list.Add("a");
list.Add("b");
list.Add("c");
list.Add("d");
//遍历
foreach (string item in list)
{
Console.WriteLine($"{item}-");
}
Console.ReadKey();
//stack是Stack集合的泛型集合
Stack stack = new Stack();
//压栈
stack.Push("a");
stack.Push("b");
stack.Push("c");
//查看数量和栈顶元素
Console.WriteLine(stack.Count);//3
Console.WriteLine(stack.Peek());//c
//出栈
Console.WriteLine(stack.Pop());
Console.WriteLine(stack.Pop());
Console.WriteLine(stack.Pop());
Console.WriteLine(stack.Count);//0
Console.ReadKey();
//Queue是Queue集合的泛型集合
Queue queue = new Queue();
//进队列
queue.Enqueue("a");
queue.Enqueue("b");
queue.Enqueue("c");
//查看数量和队首元素
Console.WriteLine(queue.Count);//3
Console.WriteLine(queue.Peek());//a
//出对列
Console.WriteLine(queue.Dequeue());//a
Console.WriteLine(queue.Dequeue());//b
Console.WriteLine(queue.Dequeue());//c
Console.WriteLine(queue.Count);//0
Console.ReadKey();
//Dictionary泛型集合是Hashtable集合的泛型集合即可以指定存储数据类型的集合
Dictionary dic = new Dictionary();
//增操作
dic.Add(1, "乌鲁木齐");
dic.Add(2, "喀什");
dic.Add(3, "吐鲁番");
//查操作
Console.WriteLine(dic.Count);//3
Console.WriteLine(dic[1]);//乌鲁木齐
//改操作
dic[1] = "伊利";
Console.WriteLine(dic[1]);//伊利
//删除操作
dic.Remove(1);
Console.WriteLine(dic.Count);//2
dic.Add(1, "乌鲁木齐");
//遍历
foreach (int key in dic.Keys)//通过键遍历
{
Console.WriteLine($"{key}-{dic[key]}");
}
foreach (string value in dic.Values)//通过值遍历
{
Console.WriteLine($"{value}");
}
foreach (KeyValuePair item in dic)
{
Console.WriteLine($"{item.Key}-{item.Value}");
}
Console.ReadKey();
LinkedList
数据结构:数据结构就是指计算机在内存中组织数据的一种方式,数组
数据结构的分类:线性结构:数组,链表,哈希表。非线性结构:树,图。
链表:单向链表:数据,存储下一个数据的地址。双向链表:存储下一个数据的地址,数据,存储下一个数据的地址。
数组和链表数据结构的区别:数组:地址连续,长度不可变,使用的时候更加适合查询操作。链表:地址不连续,长度可变化,使用的时候更加适合增删改查操作
//创建空容器
LinkedList list = new LinkedList();
//增操作
list.AddFirst("a");
list.AddLast("D");
list.AddBefore(list.Find("D"), "C");//addbefore在指定节点前面添加
//遍历
foreach (string name in list)
{
Console.WriteLine(name);//a C D
}
//查操作
Console.WriteLine(list.Count);//3
Console.WriteLine(list.First);
//linkedListNode包含三个部分;previous,value,next
Console.WriteLine(list.Last);
//获取linkedListNode链表节点对象的各个属性
Console.WriteLine(list.Last.Previous.Value);//C
Console.WriteLine(list.First.Next.Value);//C
//反向查找
Console.WriteLine(list.Last.Previous.Previous.Value);//a
//改操作
list.First.Value= "A";
Console.WriteLine(list.First.Value);
//删除操作
list.RemoveFirst();
list.RemoveLast();
list.Remove("C");
Console.WriteLine(list.Count);
//清空操作
list.Clear();
Console.ReadKey();
}