深入解析泛型

news2025/4/16 8:00:30

一、泛型的诞生

        在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.coloradmin.cn/o/1346686.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小梅哥Xilinx FPGA学习笔记17——模块化设计基础之加减法计数器

目录 一&#xff1a; 章节导读 1.1 任务要求 1.2 模块功能划分 二&#xff1a; 代码设计 2.1 灯控制逻辑&#xff08;led_ctrl&#xff09; 2.2 按键消抖模块&#xff08;key_filter&#xff09; 2.3 顶层模块&#xff08;key_led&#xff09; 2.4 引脚绑定 一&#x…

报表控件FastReport VCL 中的新 S3 传输 (Amazon)

在本文中&#xff0c;我们将探讨新的 S3 传输。从功能上来说&#xff0c;S3 与大多数人习惯使用的有很大不同&#xff0c;因此在本文的开头&#xff0c;我们将详细介绍它的主要功能。 FastReport .NET 是适用于.NET Core 3&#xff0c;ASP.NET&#xff0c;MVC和Windows窗体的全…

java maven项目添加oracle jdbc的依赖

一般添加依赖是直接在pom.xml中添加配置即可&#xff0c;Maven会自动获取对应的jar包&#xff0c;但是oracle驱动依赖添加后会显示红色&#xff0c;代表找不到依赖项&#xff0c;是因为Oracle授权问题&#xff0c;Maven3不提供Oracle JDBC driver&#xff0c;为了在Maven项目中…

LinkSLA管家式运维:为企业打造定制化 IT 支持体系

引言 在数字化转型的浪潮中&#xff0c;企业信息系统繁多&#xff0c;涉及人员复杂&#xff0c;且企业经营管理活动对IT系统的依赖程度越来越高。传统的运维模式已经不能满足企业对运维工作全面性、灵活性、稳定性和安全性的需求。管家式运维作为一种新型服务模式&#xff0c;…

CUDA安装与Tensorflow1-gpu环境搭建(windows版)

一、前提说明 1.1 Tensorflow-gpu环境搭建基本步骤 (1)明确环境搭建资源需求与下载 (2)安装CUDA与cuDNN (3)用Anaconda搭建tensorflow-gpu环境 (4)tensorflow-gpu环境测试 1.2 个人说明 由于科研需要复现机器学习、深度学习某些经典实验&#xff0c;这…

商品销售数据爬取分析可视化系统 爬虫+机器学习 淘宝销售数据 预测算法模型 大屏 大数据毕业设计(附源码)✅

毕业设计&#xff1a;2023-2024年计算机专业毕业设计选题汇总&#xff08;建议收藏&#xff09; 毕业设计&#xff1a;2023-2024年最新最全计算机专业毕设选题推荐汇总 &#x1f345;感兴趣的可以先收藏起来&#xff0c;点赞、关注不迷路&#xff0c;大家在毕设选题&#xff…

网络层解读

基本介绍 概述 当两台主机之间的距离较远(如相隔几十或几百公里&#xff0c;甚至几千公里)时&#xff0c;就需要另一种结构的网络&#xff0c;即广域网。广域网尚无严格的定义。通常是指覆盖范围很广(远超过一个城市的范围)的长距离的单个网络。它由一些结点交换机以及连接这些…

numpy数组04-数组的轴和读取数据

一、数组的轴 在numpy中数组的轴可以理解为方向&#xff0c;使用0&#xff0c;1&#xff0c;2...数字表示。 对于一个一维数组&#xff0c;只有一个0轴&#xff0c;对于2维数组&#xff08;如shape&#xff08;2&#xff0c;2&#xff09;&#xff09;&#xff0c;有0轴和1轴…

Windows搭建RTSP视频流服务(EasyDarWin服务器版)

文章目录 引言1、安装FFmpeg2、安装EasyDarWin3、实现本地\虚拟摄像头推流服务4、使用VLC或PotPlayer可视化播放器播放视频5、RTSP / RTMP系列文章 引言 RTSP和RTMP视频流的区别 RTSP &#xff08;Real-Time Streaming Protocol&#xff09;实时流媒体协议。 RTSP定义流格式&am…

idea利用JRebel插件,无需重启,实现Spring Boot项目热重载,节省开发时间和精力!

插件介绍 官方介绍 翻译过来的意思是&#xff1a; JRebel 是一款提高开发效率的工具&#xff0c;允许开发者立即重新加载代码更改。它跳过了在Java开发中常见的重新构建、重启和重新部署循环。JRebel 能够让开发者在相同的时间内完成更多工作&#xff0c;并且在编码时能够保持…

付费进群系统源码带定位完整独立版(12月30日)再次修复首发

搭建教程 nginx1.2 php5.6–7.2均可 最好是7.2 第一步上传文件程序到网站根目录解压 第二步导入数据库&#xff08;shujuku.sql&#xff09; 第三步修改/config/database.php里面的数据库地址 第四步修改/config/extra/ip.php里面的域名 第四步设置伪静态thinkphp 总后台账号&…

unity控制摄像机几种视角实现方式

目录 1、按下鼠标右键可以实现摄像机上下左右旋转 2、自由视角 3、摄像头跟随视角 4、跟随自由视角 5、第一人称跟随视角 python学习汇总连接&#xff1a; 1、按下鼠标右键可以实现摄像机上下左右旋转 这段代码定义了一个名为CameraRotate的脚本&#xff0c;用于控制摄像…

Unity坦克大战开发全流程——结束场景——通关界面

结束场景——通关界面 就照着这样来拼 写代码 hideme不要忘了 修改上一节课中的代码

Java项目:103SSM酒店管理系统

博主主页&#xff1a;Java旅途 简介&#xff1a;分享计算机知识、学习路线、系统源码及教程 文末获取源码 一、项目介绍 酒店管理系统基于SpringSpringMVCMybatis开发&#xff0c;功能简单&#xff0c;可用于毕设或者课程设计。 管理员功能如下&#xff1a; 房间管理住客入住…

图像去雾/图像去雨(matlab/python)

图像去雾和图像去雨是计算机视觉领域的两个重要问题&#xff0c;旨在改善被大气条件或降雨影响而模糊或噪声化的图像质量。这两个技术在很多实际应用中具有广泛的价值&#xff0c;包括无人驾驶、安防监控、航空航天等领域。下面将分点介绍图像去雾和图像去雨的相关内容。 1. 图…

微服务(10)

目录 46.k8s中镜像的下载策略是什么&#xff1f; 47.image的状态有哪些&#xff1f; 48.如何控制滚动更新过程&#xff1f; 49.DaemonSet资源对象的特性&#xff1f; 50.说说你对Job这种资源对象的了解&#xff1f; 46.k8s中镜像的下载策略是什么&#xff1f; 可通过命令k…

IIS服务器发布PHP网站

IIS服务器&#xff0c;相信开发者都不会陌生&#xff0c;它的英文全称是Internet Information Services&#xff0c;是由微软公司提供的基于运行Microsoft Windows的互联网基本服务&#xff0c;常用于Windows系统的Web项目部署&#xff0c;本篇以PHP项目为例&#xff0c;讲解如…

循环生成对抗网络(CycleGAN)

一、说明 循环生成对抗网络&#xff08;CycleGAN&#xff09;是一种训练深度卷积神经网络以执行图像到图像翻译任务的方法。网络使用不成对的数据集学习输入和输出图像之间的映射。 二、基本介绍 CycleGAN 是图像到图像的翻译模型&#xff0c;就像Pix2Pix一样。Pix2Pix模型面临…

kotlin快速入门1

在Google I/O 2017中&#xff0c;Google 宣布 Kotlin 成为 Android 官方开发语言。目前主流AndroidApp开发已经全部切换成此语言&#xff0c;因此对于Android开发而言&#xff0c;掌握Kotlin已经变成必要事情。 Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言&#xff…

超声波防碰撞电路原理图

如图所示为超声波防碰撞电路&#xff0c;电路采用LM1812并由时基电路Ⅱ来控制LM1812的发送与接收&#xff08;LM1812,即发送又接收&#xff09;。控制距离可用Skfl的电位器来调节&#xff0c;一般可控制2-3m。时基电路1组成单稳态电路&#xff0c;当达到报警距离时&#xff0c;…