深入解析泛型

一、泛型的诞生

        在C#1 中我们还没有泛型的时候我们收集数据通常需要使用到数组,或者使用封装好的数组集合Hashtable  ArrayList。

举个例子:

        我们在读取文件的时候就会需要一个数组来储存读取的数据的内容  但我们并不知数据的具体长度也就无法在声明的时候附上准确的数组长度。

        这时我们可以使用一种较为繁琐的方法 就是声明一个数组,如果当前的数组已经被填满,那么将当前数组的数据复制到一个更加大的数组当中 ,直到数组没有被填满就将当前数组的实际有效内容复制到一个正好大小的数组当中。

    /// <summary>/// 输出数组中的所有元素/// </summary>/// <param name="arrayList"></param>static void WrileArray(System.Collections.ArrayList arrayList){foreach (int item in arrayList){System.Console.WriteLine(item);}}

调用:

  static void Main(){WrileArray(new System.Collections.ArrayList() { 1, 5, 7, 8, 9 });System.Console.ReadLine();}

提示: 在我们集合中如果一直是int数据当然不会发生任何问题,但一旦我们的集合当中有非int类型的数据则就会抛出异常。 

这种情况下我们也可以自定义一个集合类指定集合只能接收某种类型。

举个例子:

class MYcollections : System.Collections.CollectionBase
{public void Add(int str) => List.Add(str);public void Remove(int Itemm) => List.Remove(Itemm);public int MycollectionsCount => List.Count;
}

使用方式:

  static void Main(){WrileArray(new MYcollections() { 1, 5, 7, 8, 9 });System.Console.ReadLine();}

注意:这时候您在想添加非int类型的数组则不会通过编译器,但上述方法还是有点繁琐,于是我门C#2当中就推出了泛型这一概念。可以完美解决上述问题。

二、泛型

使用泛型完成上述一致的效果:

 static void Main(){WrileArray<int>(new List<int>  { 1, 5, 7, 8, 9 });System.Console.ReadLine();}/// <summary>/// 输出数组中的所有元素/// </summary>/// <param name="arrayList"></param>static void WrileArray<T>(List<T> arrayList){foreach (T item in arrayList){System.Console.WriteLine(item);}}

示例解释:

         我们创建了一个List的泛型类型作为WriteAay方法的参数,其中T泛型参数的标识符代表可以为任何类型,在我们传递了类型实参的时候,泛型方法中的类型形参类型都将是类型实参的类型,如我们传递了int类型那么泛型方法当中的所有这个类型形参都将为int类型。

类型形参 类型实参 

提示:在泛型方法中,可以使用泛型类型参数作为其他泛型类或方法的类型实参。这可以使得泛型方法更加灵活和通用。如下图所示:


泛型度(arrity):指泛型类型当中的泛型形参的个数

泛型的适用范围:

        以下成员是不可能声明为泛型:字段、属性、索引器、构造器、事件、终结器。判断一个是否为泛型的唯一标准是看当前的泛型形参是否首次声明。

类型推断:

        在泛型类型中,对类型形参传输了类型实参的情况下。当前对应的类型形参,将直接为当前类型也就不在需要再次声明当前的类型形参的类型。

类型约束:

文章:C#泛型(详解)-CSDN博客


default运算符:

        default关键字可以获取当前数据类型的默认数据。如果是可空类型默认值则为Null。如果是非空类型则是类型对应的0值。

        default运算符可以用于类型形参、类型实参、用于泛型也涉及泛型形参、用于泛型也涉及泛型实参


1 对于类型形参:当在泛型类、泛型方法或泛型委托中使用泛型形参时,可以使用 default 运算符得到类型参数的默认值。例如:

T defaultValue = default(T);

2 对于类型实参:default 运算符可以用于对特定类型的实参获取默认值。例如: 

int defaultValue = default(int);

typeof 运算符:

        typeof运算符返回的类型是Type类型,可以用于泛型。使用Type类提供的一些方法和属性我们可以在泛型当中进行类型转换。

以下是 System.Type 类提供的一些常用方法和属性:

  1. GetType(): 返回当前对象的 System.Type

  2. IsAssignableFrom(Type c): 检查当前类型是否可以从指定的类型分配。

  3. IsInstanceOfType(object o): 检查当前类型是否是给定对象的实例。

  4. GetMethod(string name, Type[] parameters): 获取指定名称和参数类型的方法。

  5. GetMethods(): 获取该类型中定义的所有公共方法。

  6. GetProperty(string name): 获取指定名称的属性。

  7. GetProperties(): 获取该类型中定义的所有公共属性。

  8. IsGenericType: 检查当前类型是否为泛型类型。

  9. IsGenericTypeDefinition: 检查当前类型是否为泛型类型的定义。

  10. MakeGenericType(params Type[] typeArguments): 创建一个封闭的泛型类型,通过将类型参数替换为指定的类型参数数组。

下面是一个示例,演示了如何在泛型中使用 System.Type 类进行类型转换和操作:

public class MyGenericClass<T>
{public void PrintTypeInformation(){Type type = typeof(T);Console.WriteLine("Type name: " + type.Name);Console.WriteLine("Is generic type definition: " + type.IsGenericTypeDefinition);Console.WriteLine("Is generic type: " + type.IsGenericType);if (type.IsGenericType){Type[] typeArguments = type.GetGenericArguments();Console.WriteLine("Type arguments: ");foreach (Type argument in typeArguments){Console.WriteLine("- " + argument.Name);}Type closedType = type.MakeGenericType(typeof(string));Console.WriteLine("Closed type: " + closedType.Name);}}
}

示例解释:

        我们定义了一个名为 MyGenericClass 的泛型类,通过使用 System.Type 类的方法和属性,在 PrintTypeInformation 方法中打印了与泛型相关的类型信息。在这个例子中,我们展示了如何获取泛型参数的类型信息,并使用 MakeGenericType 方法创建了一个封闭的泛型类型,将类型参数替换为 string 类型。 

(typeof(MyGenericClass<int>), obj.GetType());

提示:当前的效果是一致的。 

 1 typeof(T)当前表达式时返回的当前类型形参T对应的类型实参的Type。它返回值永远是一个封闭的,已构造的类型。

举个例子:

public class Pair<T>
{public T First { get; set; }public T Second { get; set; }public Pair(T first, T second){First = first;Second = second;}
}

现在,我们可以创建不同类型的封闭的已构造类型,比如:

Pair<int> intPair = new Pair<int>(10, 20);
Pair<string> stringPair = new Pair<string>("Hello", "World");
Pair<bool> boolPair = new Pair<bool>(true, false);

 示例解释:

        在这些示例中,intPair 是一个封闭的已构造类型,Pair<int> 是通过将泛型类型参数 T 替换为 int 而创建的具体类型。同样,stringPairboolPair 分别是 Pair<string>Pair<bool> 的封闭的已构造类型。

2 typeof(List<>)当前的表达式看似好像是缺少参数但实际上是可以编译的。对于泛型度为1的这么写,对应泛型度为2的typeof(List<,>)泛型度为3的typeof(List<,,,>)。注意当前表达式只在typeof运算符中有效。

举个例子:

  System.Console.WriteLine(typeof(List<>));System.Console.ReadLine();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/311682.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

对I2C总线上挂接多个AT24C02的读写操作

#include <reg51.h> // 包含51单片机寄存器定义的头文件 #include <intrins.h> //包含_nop_()函数定义的头文件 #define OP_READ1 0xa1 // 器件1地址以及读取操作,0xa1即为1010 0001B #define OP_WRITE1 0xa0 // 器件1地址以…

数据结构 模拟实现LinkedList单向不循环链表

目录 一、链表的简单介绍 二、链表的接口 三、链表的方法实现 &#xff08;1&#xff09;display方法 &#xff08;2&#xff09;size得到单链表的长度方法 &#xff08;3&#xff09;addFirst头插方法 &#xff08;4&#xff09;addLast尾插方法 &#xff08;5&#xf…

【深度解析C++】const成员函数

系列文章目录 &#x1f308;座右铭&#x1f308;&#xff1a;人的一生这么长、你凭什么用短短的几年去衡量自己的一生&#xff01; &#x1f495;个人主页:清灵白羽 漾情天殇_计算机底层原理,深度解析C,自顶向下看Java-CSDN博客 ❤️相关文章❤️&#xff1a;Cthis指针&#xf…

特殊权限(suid sticky acl mask)

1.suid 1. 普通用户可不可以修改密码&#xff1f; 答&#xff1a;是可以的&#xff0c;可以修改自己的密码 2. /etc/shadow 文件的作用是什么&#xff1f; 答&#xff1a;存储用户密码的文件 3. 普通用户是否可以修改/etc/shadow 文件&#xff1f; 答&#xff1a;不可以&…

CSDN - 从CSDN下载自己上传的资源要下载码, 自己无法下载

从CSDN下载自己上传的资源要下载码, 自己无法下载 概述 程序里面要用一个参数文件的加解密类, 想到自己以前上传到csdn有demo. 就去下载自己上传的demo. 无法下载, 需要下载码. 也不知道这下载码怎么获得? 按照提示去关注CSDN官方的号, 关注了之后没啥反应, 应该是以前关注过…

java中PhantomReference WeakReference SoftReference垃圾回收触发时机以及使用场景

目录 强引用 垃圾回收触发时机 使用场景 SoftReference&#xff08;软引用&#xff09; 垃圾回收触发时机 使用场景 WeakReference &#xff08;弱引用&#xff09; 垃圾回收触发时机 使用场景 PhantomReference &#xff08;虚引用、幽灵引用&#xff09; 垃圾回收…

2023-12-22 LeetCode每日一题(得到山形数组的最少删除次数)

2023-12-22每日一题 一、题目编号 1671. 得到山形数组的最少删除次数二、题目链接 点击跳转到题目位置 三、题目描述 我们定义 arr 是 山形数组 当且仅当它满足&#xff1a; arr.length > 3存在某个下标 i &#xff08;从 0 开始&#xff09; 满足 0 < i < arr.…

arkts中@Watch监听的使用

概述 Watch用于监听状态变量的变化&#xff0c;当状态变量变化时&#xff0c;Watch的回调方法将被调用。Watch在ArkUI框架内部判断数值有无更新使用的是严格相等&#xff08;&#xff09;&#xff0c;遵循严格相等规范。当在严格相等为false的情况下&#xff0c;就会触发Watch的…

软件开发新手用哪个IDE比较好?软件开发最好的IDE都在这!

目录 IDES 的优点 最佳编程 IDE 列表 Java 开发的流行集成开发环境 JetBrains 的 IntelliJ IDEA NetBeans 适用于 C/ C、C# 编程语言的最佳 IDE Visual Studio 和 Visual Studio 代码 Eclipse PHP 开发的最佳 IDE PHPStorm Sublime Text Atom JavaScript 的顶级 I…

2024年,程序员有哪些危机,有什么应对方式?

在2024年&#xff0c;程序员可能面临的危机主要包括技术更新迅速、职业竞争激烈、工作与生活平衡困难等方面。 为了应对这些危机&#xff0c;程序员可以采取以下策略&#xff1a; 技术更新迅速&#xff1a;随着技术的不断发展&#xff0c;新的编程语言和工具不断涌现&#xff…

大模型请回答2023 :A股能否突破3000点,贾跃亭何时回国?

2023年&#xff0c;国内最少已经有238个公开大模型。 但要回答关于2023年的问题&#xff0c;238个大模型还远远不够。 2023年&#xff0c;站在一个共识被打碎的十字路口。文明的黄金时代逐渐落幕&#xff0c;增长不再是全球经济的理所当然&#xff0c;每一个行业的都面临着新…

研究:同样的C++模板在多个cpp里出现,编译器是否要重复生成?

2023年就要过去&#xff0c;马上要跨如2024年。祝大家在新的一年&#xff0c;有个好收成。 一直以来不是很确定&#xff1a; 同样的的模板&#xff0c;在各个cpp分别出现&#xff0c;编译器要实现几份&#xff1f; 研究一下。 用命令行的编译方法&#xff0c;参考&#xff1a…