C#中的泛型

目录

一、泛型的类型参数T

二、创建泛型接口

1.接口及约束定义

2.示例

三、创建泛型方法


        泛型是C# 和公共语言运行库(CLR)中的一个功能,这是一种可以使程序支持不同类型的技术。它将类型参数的概念引入.NET Framework中,类型参数将一个或多个类型的指定推迟到客户端代码声明并实例化该类或方法。即,泛型允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型。

        泛型是用于处理算法、数据结构的一种编程方法。泛型的目标是采用广泛适用和可交互性的形式来表示算法和数据结构,以使它们能够直接用于软件构造。泛型类、结构、接口、委托和方法可以根据它们存储和操作的数据的类型来进行参数化。泛型能在编译时提供强大的类型检查,减少数据类型之间的显示转换、装箱操作和运行时的类型检查。泛型类和泛型方法同时具备可重用性、类型安全和效率高等特性,这是非泛型类和非泛型方法无法具备的。泛型通常用在集合和在集合上运行的方法中。泛型主要是提高了代码的重用性。        

一、泛型的类型参数T

        泛型的类型参数T 可以看作 是一个占位符,它不是一种类型,它仅代表了某种可能的类型 。在定义泛型 时T 出现的位置可以在使用时用任何类型来代替。
类型参数T的命名准则如下://使用描述性名称命名泛型类型参数,除非单个字母名称完全可以让人了解它表示的含义,而描述性名称不会有更多的意义。
public interface ISessionChannel<Session>
public delegate TOutput Converter<Input,Output>//将T作为描述性类型参数名的前缀
public interface ISessionChannel<TSession>
{TSession Session{get;}
}

二、创建泛型接口

1.接口及约束定义

        泛型接口的声明形式如下:

interface [接口名] <T>
{[接口体]
}

        声明泛型接口时,与声明一般接口的唯一区别是增加了一个<T>。一般来说,声明泛型接口与声明非泛型接口遵循相同的规则。泛型类型声明所实现的接口必须对所有可能的构造类型都保持唯一。否则就无法确定该为某些构造类型调用哪个方法。

        在实例化泛型时也可以使用约束对类型参数的类型种类施加限制,约束是使用where上下文关键字指定的。下面列出了6种类型的约束。

约束

说明

T:结构

类型参数必须是值类型。可以指定除Nullable以外的任何值类型

T:类

类型参数必须是引用类型。这一点也适用于任何类、接口、委托或数组类型

T:new()

类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时,new()约束必须最后指定。

T:<基类名>

类型参数必须是指定的基类或派生自指定的基类。

T:<接口名称>

类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。

T:U

为T提供的类型参数必须是为U提供的参数或派生自为U提供的参数。这称为裸类型约束。

2.示例

// 泛型
using System.ComponentModel;namespace _01
{/// <summary>/// 创建一个泛型接口/// 接口中调用CreateInstance方法/// </summary>/// <typeparam name="T"></typeparam>public interface IGenericInterface<T>{T CreateInstance();}/// <summary>/// 实现上面泛型接口的泛型类,创建一个公共方法CreateInstance/// 派生约束where T : TI(T要继承自TI)/// 构造函数约束where T : new()(T可以实例化)/// </summary>/// <typeparam name="T"></typeparam>/// <typeparam name="TI"></typeparam>public class Factory<T, TI> : IGenericInterface<TI> where T : TI, new(){public TI CreateInstance(){return new T();}}class Program{/// <summary>/// 注释掉的部分是一种实现,但会引起警告CA1859/// 内联临时变量后不需要实例化接口,并且解决警告CA1859/// 输出指定泛型的类型/// </summary>static void Main(){//实例化接口//IGenericInterface<System.ComponentModel.IListSource> factory = new Factory<System.Data.DataTable, System.ComponentModel.IListSource>();//Console.WriteLine(factory.CreateInstance().GetType().ToString());Console.WriteLine(new Factory<System.Data.DataTable, IListSource>().CreateInstance().GetType().ToString());Console.ReadLine();}}
}
/*运行结果:System.Data.DataTable    */

三、创建泛型方法

        泛型方法是在声明中包括了类型参数T的方法。泛型方法可以在类、结构或接口声明中声明,这些类、结构或接口本身可以是泛型或非泛型的。如果在泛型类型声明中声明泛型方法,则方法体可以同时引用该方法的类型参数T和包含该方法的声明的类型参数T。泛型方法可以使用多类型参数进行重载。       

//泛型方法的声明形式如下:
[修饰符] Void [方法名] <类型参数T>
{[方法体]
}

         示例:在数组中查找某一数值的位置

// 泛型方法
// 通过定义一个泛型方法,查找数组中某个数字的位置
namespace _02
{public class Finder										//建立一个公共类Finder{/// <summary>/// 创建泛型方法/// </summary>/// <typeparam name="T">泛型类型</typeparam>/// <param name="items">数组变量</param>/// <param name="item">指定的某个数值常量</param>/// <returns>"i,从0起的数组索引号"</returns>public static int Find<T>(T[] items, T item){for (int i = 0; i < items.Length; i++)	//调用for循环{if (items[i]!.Equals(item))		    //调用Equals方法比较两个数{return i;						//返回相等数在数组中的位置}}return -1;								//如果不存在指定的数,则返回-1}}class Program{/// <summary>/// 在泛型数组中查询并输出=6的元素的索引号/// </summary>static void Main(string[] args){int i = Finder.Find([1, 2, 3, 4, 5, 6, 8, 9], 6); Console.WriteLine("6在数组中的位置:" + i.ToString());Console.ReadLine();}}
}
/*6在数组中的位置:5    */

        用泛型方法来表达,思路太清晰了。

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

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

相关文章

Mybatis-plus常见标签

1.< 代表小于号&#xff08;<&#xff09;2.> 代表大于号&#xff08;>&#xff09;3.&le; 代表小于或等于符号&#xff08;≤&#xff09;4.&ge; 代表大于或等于符号&#xff08;≥&#xff09;5.< 代表<6.> 代表>7.ne; 代表不等于 <>8…

【图像加密】Arnold置乱和混沌加密-MATLAB代码

Arnold Arnold.m function [img_new] Arnold(a,b,h,w,n,img) % h64; % w64;img_new zeros(h,w) ; %[h, w]size(img) % a 5; % b 6; % n 16; %n为置乱轮数N h;for i1:nfor y1:hfor x1:wxxmod((x-1)b*(y-1),N)1; %a,b可提前指定yymod(a*(x-1)(a*…

LeetCode [简单] 160. 相交链表

给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 题目数据 保证 整个链式结构中不存在环。 注意&#xff0c;函数返回结果后&#xff0c;链表必须 保持其原始结构 。 160.…

【Flutter 常见问题系列 第 1 篇】Text组件 文字的对齐、数字和字母对齐中文

TextStyle中设置height参数即可 对齐的效果 Text的高度 是根据 height 乘于 fontSize 进行计算的、这里指定heiht即可、不指定的会出现 无法对齐的情况&#xff0c;如下&#xff1a; 这种就是无法对齐的情况

Qt4用子类化ProxyModel和子类化MainWindow实现全表筛选,中文排序和复制粘贴

目录 1 需求 2 子类化ProxyModel实现全表筛选 3 字符串列表实现中文排序 3.1 Qt5中文排序 3.2 Qt4排序 4 表格的复制粘贴 5 应用 1 需求 模型视图编程是Qt开发的基本功&#xff0c;其中有几个关键问题需要解决&#xff1a; 全表筛选&#xff0c;或者说多列搜索中文排序…

Linux服务器SSH客户端断开后保持程序继续运行的方法

目录 1. nohup 命令&#xff1a; 2. tmux 或 screen&#xff1a; 3 final shell 断开后服务器如何继续执行令&#xff1f; 方法一&#xff1a;使用 nohup 命令 方法二&#xff1a;将命令放在后台执行 4 你可以使用 jobs 命令查看当前终端中正在后台运行的任务 &#xff…

决策树(第四周)

一、决策树基本原理 如下图所示&#xff0c;是一个用来辨别是否是猫的二分类器。输入值有三个&#xff08;x1&#xff0c;x2&#xff0c;x3&#xff09;&#xff08;耳朵形状&#xff0c;脸形状&#xff0c;胡须&#xff09;&#xff0c;其中x1{尖的&#xff0c;圆的}&#xf…

叠加原理(superposition principle)、线性系统

叠加原理&#xff08;superposition principle&#xff09;&#xff1a;指对一个系统而言&#xff0c;两个或多个输入产生的输出&#xff0c;等于这几个输入单独引起的输出的和&#xff0c;即输入的叠加等于各输入单独引起的输出的叠加。 线性系统&#xff1a;一个系统&#x…

Centos 7 更改 PostgreSQL 14 默认存储路径

前言&#xff1a; 默认PostgreSQL数据存储路径为&#xff1a;/var/lib/pgsql/14/data 迁移到新的存储路径&#xff1a;/mnt/postgresql/data 1、关闭PostgreSQL服务 systemctl stop postgresql-142、创建目录 # 创建新目录 mkdir -p /mnt/postgresql/data# 更改目录权限 chow…

vscode中pylance无法显示outline无法跳转

当打开的workspce中有较多的文件时&#xff0c;pylance需要分析的文件太多&#xff0c;导致卡住&#xff0c;无法分析到对应的python文件 常见的情况是&#xff0c;当我们在workspace中包含了data文件夹&#xff08;通常是通过软连接方式把数据集链接过来&#xff09;&#xf…

手机无法投屏到电脑(跨屏互联)无法使用

可能是因为windows防火墙的原因&#xff0c;将防火墙关闭即可

常用的Linux的指令

目录 常用指令 1、文件和目录操作&#xff1a; 2、文件查看和编辑 3、系统信息 4、进程管理 5、用户和权限 6、网络操作 7、压缩和解压 8、软件包管理 常用指令 1、文件和目录操作&#xff1a; ls&#xff1a;列出目录内容 cd&#xff1a; 切换目录 pwd&#xff1a;显…

十分钟让你搞懂JVM中的GC垃圾回收机制(分代回收)

文章目录 0. 为什么要有垃圾回收?1. 垃圾回收哪个内存区域?2. 如何找到垃圾(死亡对象的判断)2.1 引用计数法2.2 可达性分析法2.3 两种算法的差别 3. 如何清理垃圾(死亡对象的回收)3.1 标记-清楚法3.2 复制法3.3 标记-整理法 4. JVM使用的回收方法4.1 什么是分代回收4.2 哪些对…

SCA软件成分分析技术原理浅析

SCA软件成分分析工具可以通过静态和动态有两种技术方式实现&#xff1a; 静态分析&#xff1a;通过对源代码或二进制程序进行分析&#xff0c;从而识别被检测项目中包含的开源组件&#xff0c;开源组件本身包含的已知漏洞、组件版本信息、许可证信息等便可以查询得到&#xff…

sqlite外键约束 保证数据一致性

1. 外键约束 在SQLite中&#xff0c;可以通过使用外键&#xff08;Foreign Key&#xff09;约束和CASCADE选项来实现通过外键删除相关信息。 CASCADE选项是指在主键表中删除记录时&#xff0c;相应的外键表中的相关记录也将被自动删除。 -- 创建主键表 CREATE TABLE Persons…

JVM——几种常见的对象引用

目录 1. 软引用软引用的使用场景-缓存 2.弱引用3.虚引用和终结器引用 可达性算法中描述的对象引用&#xff0c;一般指的是强引用&#xff0c;即是GCRoot对象对普通对象有引用关系&#xff0c;只要这层关系存在&#xff0c; 普通对象就不会被回收。除了强引用之外&#xff0c;Ja…

C++局域网从服务器获取已连接用户的列表(linux to linux)

目录 服务器端 代码 客户端 代码解析 服务器端 原理 遇到的阻碍以及解决办法 客户端 原理 遇到的阻碍以及解决办法 运行结果截图 总结 服务器端 代码 #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <netinet…

深入了解 Pinia:现代 Vue 应用的状态管理利器

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

【Python】用三种方法创建tkinter桌面窗口

Python的tkinter是Python的标准GUI库之一&#xff0c;它是一个开源的、跨平台的GUI工具包&#xff0c;可以用于创建桌面应用程序。 tkinter提供了许多常见的GUI组件&#xff0c;例如按钮、文本框、标签、列表框等等&#xff0c;可以轻松地创建各种类型的桌面应用程序。它还支持…

云服务器上部署 Web 项目及端口异常处理

文章目录 1. 在云服务器的 MySQL(MariaDB) 中, 建库建表2. 微调代码3. 打包4. 把 war 包 拷贝到云服务器上端口被占用处理 1. 在云服务器的 MySQL(MariaDB) 中, 建库建表 在云服务器中进入 MySQL mysql -u root -p把之前本地写好的 SQL 代码一粘贴即可 例如: -- 这个文件主要…