C# 泛型的使用

01

泛型概述

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

       泛型主要是提高了代码的重用性,例如,可以将泛型看成是一个可以回收的包装箱 A。如果在包装箱 A 上贴上苹果标签,就可以在包装箱A 里装上苹果进行发送;如果在包装箱 A 上贴上地瓜标签就可以在包装箱 A 里装上地瓜进行发送。

02


泛型的使用

       在下面内容中将会详细介绍泛型的类型参数 T,以及如何创建泛型接口和泛型方法,并且通过实例演示泛型接口和泛型方法在程序中的应用。

1. 类型参数T

泛型的类型参数 T 可以看作是一个占位符,它不是一种类型,它仅代表了某种可能的类型。类型参数T可以在使用时用任何类型来代替。类型参数T的命名准则如下。

      8f8781fb22d8f548c454ceda2c203b06.png  使用描述性名称命名泛型类型参数,除非单个字母名称完全可以让人了解它表示的含义,而描述性名称不会有更多的意义。

     【例1】 使用代表一定意义的单词作为类型参数T的名称。

      代码如下:

   public interface ISessionChannel<Session>

   public delegate TOutput Converter<input, Output>

     da37209c9081fe5cb36592af6e226929.png  将T作为描述性类型参数名的前缀。

    【例2】 使用T作为类型参数名的前缀。

      代码如下:

public interface ISessionChannel<TSession>{     TSession Session{ get;}}

2.  泛型接口

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

interface 【接口名】<T>

{

          【接口体】

}

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

       说明 

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

      ① T:结构——类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型。

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

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

      ④ T:<基类名>——类型参数必须是指定的基类或派生自指定的基类。

      ⑤ T:<接口名称>——类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束,约束接口也可以是泛型的。

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

     【例3】 创建一个控制台应用程序,首先创建一个 Factory 类,在该类中建立一个CreateInstance方法。然后再创建一个泛型接口,在这个泛型接口中调用 Createlnstance 方法。根据类型参数 T,获取其类型。

      代码如下:

//创建一个泛型接口public interface IGenericInterface<T>{     T CreateInstance();    //接口中调用 CreateInstance 方法 }//实现上面泛型接口的泛型类//派生约束 where T: TI(T 要继承自 TI)//构造函数约束 where T:new()(T 可以实例化)public class Factory<T,TI>;IGenericInterface<TI> where T: TI,new(){     public TI CreateInstance()    //创建一个公共方法 CreateInstance{          return new T();    }
}
class Program
{    static void Main(string[] args)    {//实例化接口         IGenericInterface<System.ComponentModel.IListSource> factory =new Factory<System.Data.DataTable,System.ComponentModel.IListSource>();   //输出指定泛型的类型         Console.WriteLine(factory.CreateInstance().GetType().ToString());  Console.ReadLine();    }
}

程序的运行结果如图1 所示。

d5d7b949a14b4b4ad8eedd71eff89741.png

图1  泛型接口应用

3.  泛型方法

泛型方法的声明形式如下:

【修饰符】 Void 【方法名】<类型参数T>

{

    【方法体】

}

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

说明

       泛型方法可以使用多类型参数进行重载。

     【例4】 创建一个控制台应用程序,通过定义一个泛型方法来查找数组中某个数字的位置。

      代码如下:

public class Finder     //建立一个公共类 Finder{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
{static void Main(string[] args){int i= Finder.Find<int>(new int[](1,2,3,4,5,6,8,9),6);    //调用泛型方法,并定义数组指定数字 Console.WriteLine("6 在数组中的位置:"+i.ToString());     //输出中数字在数组中的位置 Console.ReadLine();}
}

程序的运行结果是“6 在数组中的位置为5”。

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

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

相关文章

80040e14 mysql_【ASP】提示错误80040e14

是的&#xff0c;提示Cls_vbsPage.asp 行164 有问题&#xff0c;整个代码如下&#xff1a;Class Cls_vbsPagePrivate oConn 连接对象Private iPagesize 每页记录数Private sPageName 地址栏页数参数名Private sDbType数据库类型,AC为access,MSSQL为SQL SERVER2000…

在数学世界,都有这些美妙的数学公式是你不认识的......

全世界只有3.14 % 的人关注了爆炸吧知识什么是数学&#xff1f;华罗庚说&#xff1a;宇宙之大&#xff0c;粒子之微&#xff0c;火箭之速&#xff0c;化工之巧&#xff0c;地球之变&#xff0c;生物之谜&#xff0c;日用之繁&#xff0c;无处不用数学......回首往昔&#xff0c…

Android MediaScanner:(一)MediaScanner总体架构

Android MediaScanner&#xff1a;&#xff08;一&#xff09;MediaScanner总体架构 分类&#xff1a; Android android.multimedia2012-05-19 18:29 5050人阅读 评论(5) 收藏 举报androidservice数据库工作interfaceinsert田海立csdn 2012-05-19 本文是笔者的分析归纳&#xf…

协变和逆变

http://msdn.microsoft.com/zh-cn/library/vstudio/dd997386.aspx转载于:https://www.cnblogs.com/mingyongcheng/archive/2012/11/15/2771568.html

报表系统FineReport通过权限控制数据访问方案

2019独角兽企业重金招聘Python工程师标准>>> 问题&#xff1a;实际应用环境中&#xff0c;不同角色的人可能对数据具有不同的访问权限&#xff0c;通过直接在SQL语句中筛选出需要的数据制作模板可以解决该需求&#xff0c;但对于角色较多的情况&#xff0c;就需要制…

SkyWalking配上告警更优秀

前言对于监控系统来说&#xff0c;不可能让人一直盯着监控看板&#xff0c;而更多的是以自动提醒的方式&#xff0c;比如邮件、短信或微信推送等&#xff0c;当达到或超出预设的告警指标时&#xff0c;就自动发送消息提醒&#xff0c;下面就来说说如何配置SkyWalking的告警。正…

python sqllite远程_Python实现Sqlite将字段当做索引进行查询的方法

本文实例讲述了Python实现Sqlite将字段当做索引进行查询的方法。分享给大家供大家参考&#xff0c;具体如下&#xff1a;默认从sqlite中获取到的数据是数字索引的, 在开发阶段经常有修改数据库所以显得不太方便, 其实在python源码里就有解决方案, 直接读sqlite3的源码, 摸索了一…

神抓拍!2020搞笑野生动物摄影大赛,哈哈哈哈哈笑到头掉

全世界只有3.14 % 的人关注了爆炸吧知识图片来自CWPAs 2020小动物们到底能有多好玩让我们来看看今年的搞笑野生动物摄影大赛吧保准叫你从头笑到尾&#xff08;以下是入围作品&#xff09;“飚自行车的”猴看起来像个酷猴▲摄影&#xff1a;Yevhen Samuchenko真情实感演绎“我太…

【转载】ESFramewor使用技巧(2)-- 在插件中使用NHibernate

ESFramewor使用技巧&#xff08;2&#xff09;&#xff0d;&#xff0d; 在插件中使用NHibernate 我们来讨论一下这种情景&#xff0c;你采用基于ESFramework的4层架构进行应用开发&#xff0c;你分析用户的需求&#xff0c;并将其分类整理为几大块&#xff0c;考虑每一块使用…

如何在ashx页面获取Session值(未将对象引用设置到对象的实例) (转)

如何在ashx页面获取Session值(未将对象引用设置到对象的实例) 分类&#xff1a; .Net学习笔记 Session 2011-11-30 10:25 902人阅读 评论(1) 收藏 举报在一般事务处理页面&#xff0c;可以轻松的得到 Request,Response对象&#xff0c;从而进行相应的操作&#xff0c;如下&am…

java字符串从后截取_java 字符串截取的几种方式(转)

众所周知,java提供了很多字符串截取的方式。下面就来看看大致有几种。 1.split()+正则表达式来进行截取。 将正则传入split()。返回的是一个字符串数组类型。不过通过这种方式截取会有很大的性能损耗,因为分析正则非常耗时。 String str = "abc,12,3yy98,0"; Strin…

REST 深度进阶

最近团队人数在扩大&#xff0c;才发现&#xff0c;REST 这个出来很多年头的东西&#xff0c;居然还有人用不好。说起来&#xff0c;REST 出现已经很久了。从早期的三层架构&#xff0c;到现在的多层、微服务&#xff0c;核心内容之一就是 API --- 从非常简单的 API&#xff0c…

绝不翻车珍珠奶茶做法

1 如何在家自制珍珠奶茶▼2 儿子&#xff0c;妈妈给你烤小饼干哦▼3 放假太久了连自己哪个班都忘了▼4 想问下&#xff0c;鸟是在哪都能起窝吗&#xff1f;▼5 不到万不得已&#xff0c;绝不去做▼6 这个店名太童年阴影了▼7 小鸡做错了什么&#xff1f;▼你点的每个赞&…

margin三个值

http://www.cnblogs.com/wangkongming/p/3204734.html margin标记可以带一个、二个、三个、四个参数&#xff0c;各有不同的含义。 margin: 20px;&#xff08;上、下、左、右各20px。&#xff09;margin: 20px 40px;&#xff08;上、下20px&#xff1b;左、右40px。&#xff09…

循环控制for

<?php/***燕十八 公益PHP培训课堂地址:YY频道88354001 学习社区:www.zixue.it **/ /***for(初始条件1;判断条件2;4:钱减少) {执行语句3; }***/for($i10; $i >1; $i--) {echo $i,<br />; }/** 扩展一下for循环,同时循环两个数 打印 5 1 4 2 3 3 2 4 1 5 **/f…

常用JS代码大全

事件源对象 event.srcElement.tagName event.srcElement.type捕获释放 event.srcElement.setCapture(); event.srcElement.releaseCapture(); 事件按键 event.keyCode event.shiftKey event.altKey event.ctrlKey事件返回值 event.returnValue鼠标位置 event.x event.y窗体活…

施一公:“中国式科研”误国误民!表面上一片繁荣,实则深藏危机

全世界只有3.14 % 的人关注了爆炸吧知识论文和科技实力是两回事在全国政协十三届一次会议上&#xff0c;中国科学院院士、清华大学原副校长施一公曾说道&#xff1a;“我以前曾经预测&#xff0c;中国会在2020年论文数超过美国&#xff0c;没想到我们提前完成了。”但面对这项数…

正确使用和理解C#中的闭包

定义 我们把在Lambda表达式(或匿名方法)中所引用的外部变量称为捕获变量。而捕获变量的表达式就称为闭包。捕获变量 捕获的变量会在真正调用委托时“赋值”&#xff0c;而不是在捕获时“赋值”&#xff0c;即总是使用捕获变量的最新的值。如下代码所示&#xff0c;调用委托时&a…

java merge css_一句命令快速合并 JS、CSS

在项目开发环境下&#xff0c;我们会把 JS 代码尽可能模块化&#xff0c;方便管理和修改&#xff0c;这就避免不了会出现一个项目自身 JS 文件数量达到 10 个或者更多。而项目上线后&#xff0c;会要求将所有 JS 文件合并为 1 个或者几个&#xff0c;手动的操作虽然也不是问题&…

tomcat对于web.xml的security-constraint使用的处理机制

知识点 web.xml中<security-constraint> 的子元素 <http-method> 是可选的&#xff0c;如果没有 <http-method> 元素&#xff0c;这表示将禁止所有 HTTP 方法访问相应的资源。子元素 <auth-constraint> 需要和 <login-config> 相配合使用&#x…