c#面向对象(四)

前言

//用百度的文言一心得到的
泛型是一种编程语言的特性,它可以在类型之间进行通用的数据传递和操作,从而使代码的设计更加灵活和方便。泛型主要包括以下几个方面的知识点:

泛型类、泛型接口、泛型方法、泛型委托等概念:这些概念是泛型编程中的基础,需要理解它们的定义、实现和应用场景。
泛型约束:泛型类型之间的依赖关系可以用泛型约束来表示,它可以帮助程序员更好地控制泛型类型之间的依赖关系。
协变、逆变:泛型编程中经常需要对参数进行协变和逆变操作,以适应不同的数据类型和操作方式。
泛型缓存:泛型编程中经常需要对数据进行缓存,以提高程序的性能和并发性。
泛型应用场景:泛型的应用场景非常广泛,包括自动化测试、数据库连接、网络通信等等。

泛型

什么是泛型

//语法糖???
//泛型:简单理解就是宽泛的不确定的一种类型
//也就是带尖括号,在使用的时候,可以随便的给他指定一个类型
//在想每个类型都要一一传递调用,而object类型直接搞定,object类型是一切类型的父类
//难道所有的类型都用object传递调用?
//那性能问题,性能安全呢?
//import!!!装箱和拆箱?
//值类型存放在栈里面,而object要传递引用类型进来(堆)。
//那么就需要把值类型转化为引用类型,再去调用object//装箱
//需要得到值类型,再从object里面引用类型那,在转化为值类型,在拿来用//拆箱
//现在就要考虑泛型了
//泛型的一个设计思想
//想一个问题泛型在计算机最后执行的时候,能够确定是什么类型吗,
//其实在进行编译后,已经可以确定是某种类型了。
//声明的时候有一个占位符,不确定它的类型
//运行的时候一定要确定类型,也就是延迟声明
//<T>:T类型参数,占位符,没有明确的类型
//传递进来的方法的参数类型

装箱和拆箱

那么就需要把值类型转化为引用类型,再去调用object//装箱

需要得到值类型,再从object里面引用类型那,在转化为值类型,在拿来用//拆箱

泛型类

//一个类可以满足不同类型的需求
//在运行之前更具不同的类型生成各自的副本
//再类声明的时候,带有尖括号给定一个类型参数
public class Abs<T>
    {

    }
    internal class Program
    {
        static void Main(string[] args)
        {
//三种调用以后,会生成三个类型
            Abs<int> a = new Abs<int>();
            Abs<string> b = new Abs<string>();
            Abs<object> c = new Abs<object>();

泛型方法

//import!!!泛型方法:
//一个方法可以支持不同类型的参数
//调用的时候指定类型
//指定的类型必须和参数类型一致
//在调用的时候,如果可以更具参数推导出类型的话,尖括号中的类型声明可以不写
  public static void Show<T>(T prarams){
            Console.WriteLine($"{prarams}");
            }
}
    internal class Program
    {
        static void Main(string[] args)
        {
            int a = 1;
            Commend.Show<int>(a);
            Commend.Show(a);

泛型约束

//定义:泛型约束指的就是声明泛型的时候指定一些约束条件,那么在使用的时候会自行进行约束条件的判断
//1
<T> where T:struct//指定的类型必须是值类型
 class Test01<T> where T:struct{}
//值类型约束,需要值类型
new Test01<int>();
//2
<T> where T:class//指定类型必须是引用类型
class Test02<T> where T:class{}
//引用类型约束
new Test02<string>();
//3
<T>where T:new()//指定类型必须有无参数的构造函数
class Test03<T> where T:new(){}
//如果是有参数会怎么样?
new Test03<mainclass>();
//4
<T> where T:类名/接口名//指定类型必须是类,接口或类,接口的子类
class Test04<T> where T:GameObjec{}
public class GameObjec{}
public class Cube:GameObjec{}
new Test04<GameObjec>();
new Test04<Cube>();
//5
class Test05<T> where T:Ienumerable{}
new Test05<Ienumerable>();
new Test05<ArrayList>();
//6
<T> where T:泛型//指定类型必须是约束泛型或约束泛型的子类型
class Test06<T,K> where T:K{}
new Test06<string,string>();
new Test06<string,object>();

协变和逆变

//定义协变out和逆变in是在接口和委托中用于修饰泛型的,主要用于定义泛型类型的使用区域
//语法:<out T> T的泛型类型只能用于返回值类型,<in T> T的泛型类型只能用于参数列表类型。
//接口中使用
interface I_out<out T>{
//协变只能是返回值类型
T move();
void Run(T speed)//?报错吗?当成什么了?参数列表?返回值?
}
interface I_in<in T>{
T move();//报错?这是当成什么了?参数列表?返回值?
//逆变只能是参数列表
void Run(T speed);
}
//委托中使用
delegate R CustomDelegate<in V,in E,out R>(V v,E e);//怎么理解呢?
//两个逆变参数参数,一个协变参数 返回值R
public static string Answer(string s,char a){
return s+a;
}
CustomDelegate<string,char,string> str=end;//存储
Console.WriteLine(str("c#",'$'));


集合

ArrayList

小理解

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();
        }
        /// <summary>
        /// 打印arraylist元素
        /// </summary>
        /// <param name="arrayList"></param>
        private static void NewMethod(ArrayList arrayList)
        {
            for (int i = 0; i < arrayList.Count; i++)
            { //count:包含的元素
                Console.Write($"{arrayList[i]},");
            }
            Console.WriteLine();
        }
    }

Stack

小理解

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 <num ; i++)
            {//弹出4,3,why?static.count在不断变化,每次弹出一个static.count减一,弹出两个的时候static.count=2
             //i也加到2了,所以2=2不成立,循环结束,解决设置成一个固定的
                Console.WriteLine(stack.Pop());
            }
            Console.WriteLine(stack.Count);//2
            //清空
            stack.Clear();
            Console.WriteLine(stack.Count);//0
            Console.ReadKey();

Queue

小理解

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<count; i++)
            //{
            //    Console.WriteLine(queue.Dequeue());
            //}
            //清空
            queue.Clear();
            Console.WriteLine(queue.Count);
            Console.ReadKey();

Hashtable

小理解

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<T>

小理解

List<T>是ArrayList集合的泛型集合/扩展,及该集合可以用于指定具体的存储数据类型。

小例子:List<string>只改泛型集合只能存储string类型的数据,T用于指定具体的类型,也是泛型

练习

   List<string> list = new List<string>();
            //增操作
            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<T>

练习

 //stack<T>是Stack集合的泛型集合
            Stack<string> stack = new Stack<string>();  
            //压栈
            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<T>

练习

 //Queue<T>是Queue集合的泛型集合
            Queue<string> queue = new Queue<string>();

            //进队列
            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<K,V>

练习

 //Dictionary<K,V>泛型集合是Hashtable集合的泛型集合即可以指定存储数据类型的集合
            Dictionary<int,string> dic = new Dictionary<int,string>();
            //增操作
            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<int,string> item in dic)
            {
                Console.WriteLine($"{item.Key}-{item.Value}");
            }
            Console.ReadKey();

LinkedList<T>

相关小知识

LinkedList<T>是底层采用双向链表数据结构实现的集合容器

数据结构:数据结构就是指计算机在内存中组织数据的一种方式,数组

数据结构的分类:线性结构:数组,链表,哈希表。非线性结构:树,图。

链表:单向链表:数据,存储下一个数据的地址。双向链表:存储下一个数据的地址,数据,存储下一个数据的地址。

数组和链表数据结构的区别:数组:地址连续,长度不可变,使用的时候更加适合查询操作。链表:地址不连续,长度可变化,使用的时候更加适合增删改查操作

视图

练习

  //创建空容器
            LinkedList<string> list = new LinkedList<string>();
            //增操作
            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();
        }

猜你喜欢

转载自blog.csdn.net/weixin_51983027/article/details/129603248