详解C#泛型(二)
一、自定义泛型方法(Generic Method),将类型参数用作参数列表或返回值的类型:
void MyFunc<T>() //声明具有一个类型参数的泛型方法
{
Type genericType = typeof(T); //在泛型方法体内部获取类型参数的类型信息
//do…
}
//调用泛型方法
MyFunc<int>();
1.声明泛型方法时,可以在参数列表中使用这个类型参数:void MyFunc<T>(T obj) { };此时在调用该泛型方法时可以省略类型参数的指定由编译器推断其类型,例如:MyFunc<int>(myNum)与MyFunc(myNum)完全等效;
2.声明泛型方法时,可以在返回值类型中使用这个类型参数:T MyFunc<T>() { return default(T); };编译器的类型推断功能不适用于仅在返回值类型中使用类型参数的情况,此种情况在调用时必须显式指定类型参数;
3.声明泛型方法时,方法的参数列表和返回值可以指定相同或不相同的类型参数,如果不相同则一般参数列表的类型参数在前,返回值的类型参数在后:U MyFunc<T, U>(T obj) { return default(U); },此时依然不能使用编译器的类型推断功能;如果相同,则在调用时可以使用编译器的类型推断功能省略类型参数的显式指定;
类型参数数量的不同,可以构成重载方法:
void MyFunc() { }
void MyFunc<T>() { }
void MyFunc<T, U>() { }
4.泛型方法中的类型参数也可以指定约束;
5.在泛型类中声明的方法,方法的参数列表和返回值可以使用泛型类的类型参数作为类型;泛型方法可出现在泛型或具体类型中,只有当方法有属于自己的类型参数时才是泛型方法,在泛型类中声明泛型方法时,二者类型参数的占位符不可以相同:
class MyClass<T> //声明一个泛型类,类型参数占位符为T
{
void MyFunc(T obj) //声明一个非泛型方法,使用泛型类的类型参数T作为参数类型
{
//do…
}
//不能声明泛型方法void MyFunc<T>,泛型方法的类型参数占位符不能与类的类型参数占位符相同
void MyFunc<U>(T obj1, U obj2) //声明一个泛型方法,类型参数占位符为U
{
//do…
}
}
class MyClass //定义一个具体类
{
void MyFunc<T>(T obj) //声明一个泛型方法
{
//do…
}
}
二、自定义泛型接口(Generic Interface),将类型参数用作参数列表或返回值的类型:
interface IMyInterface<T> //定义具有一个类型参数的泛型接口
{
void MyFunc(T obj); //声明参数为T的方法
}
//声明泛型类继承自泛型接口
public class MyClass<T> : IMyInterface<T>
{
public void MyFunc(T obj)
{
//do…
}
}
//指定类型参数为string类型,创角泛型类的实例赋值给泛型接口的变量
IMyInterface<string> iMyInterface = new MyClass<string>();
1.适用于泛型类的规则基本也适用于泛型接口;
三、自定义泛型委托(Generic Delegate),将类型参数用作参数列表或返回值的类型:
delegate void MyDelegate<T>(T obj); //定义具有一个类型参数的泛型委托,参数列表中有一个参数
void MyGenericFunc<T>(T obj) //声明一个泛型方法,参数列表中有一个参数
{
//do…
}
void MyFunc(string str)
{
//do…
}
//声明泛型委托的实例,指定类型参数为string类型,此时可匹配的方法签名为void myFunc(string str)
MyDelegate<string> myDelegate;
//赋值一个指定类型参数为string的泛型方法
myDelegate = MyGenericFunc<string>;
//添加一个参数列表为string类型的具体方法
myDelegate += MyFunc;
1.泛型委托同泛型类一样,需要在实例化时指定类型参数的类型;
2.泛型委托的实例同具体委托的实例一样,只需要方法的参数列表和返回值类型相同即可进行匹配,因此不管目标方法是指定了符合要求类型的泛型方法还是具体方法都可以进行匹配;
四、反射中的泛型:
Type myType = typeof(MyClass<>); //获取未指定任何类型参数的开放式构造类的类型信息,多个类型参数时添加,:typeof(MyClass<,>)
myType = myType.MakeGenericType(typeof(int)); //通过类型信息的实例方法MakeGenericType()构建指定所有类型参数的封闭式构造类的类型信息,如未指定所有类型参数会抛出异常ArgumentException
//也可以直接获取封闭式构造类的类型信息,当类型参数在一开始就确定时推荐使用此种方式
//myType = typeof(MyClass<int>); //多个类型参数时需要同时指定:typeof(MyClass<int, string>)
1.通过反射只可以获取未指定任何类型参数的开放式构造类的类型信息和指定所有类型参数的封闭式构造类的类型信息,即无法获取MyClass<int, >的类型信息;
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的认可是我写作的最大动力!
作者:Minotauros
出处:https://www.cnblogs.com/minotauros/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
详解C#泛型(二)的更多相关文章
- 详解C#泛型(二) 获取C#中方法的执行时间及其代码注入 详解C#泛型(一) 详解C#委托和事件(二) 详解C#特性和反射(四) 记一次.net core调用SOAP接口遇到的问题 C# WebRequest.Create 锚点“#”字符问题 根据内容来产生一个二维码
详解C#泛型(二) 一.自定义泛型方法(Generic Method),将类型参数用作参数列表或返回值的类型: void MyFunc<T>() //声明具有一个类型参数的泛型方法 { ...
- 详解C#泛型(三)
一.前面两篇文章分别介绍了定义泛型类型.泛型委托.泛型接口以及声明泛型方法: 详解C#泛型(一) 详解C#泛型(二) 首先回顾下如何构建泛型类: public class MyClass<T&g ...
- JavaScript学习笔记-实例详解-类(二)
实例详解-类(二) //===给Object.prototype添加只读\不可枚举\不可配置的属性objectId(function(){ Object.defineProperty(Object ...
- Android开发:文本控件详解——TextView(二)文字跑马灯效果实现
一.需要使用的属性: 1.android:ellipsize 作用:若文字过长,控制该控件如何显示. 对于同样的文字“Android开发:文本控件详解——TextView(二)文字跑马灯效果实现”,不 ...
- 【Java入门提高篇】Day30 Java容器类详解(十二)TreeMap详解
今天来看看Map家族的另一名大将——TreeMap.前面已经介绍过Map家族的两名大将,分别是HashMap,LinkedHashMap.HashMap可以高效查找和存储元素,LinkedHashMa ...
- CocoaPods详解之(二)----进阶篇
CocoaPods详解之----进阶篇 作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/19178709 转载请注明出处 ...
- Java源码详解系列(十二)--Eureka的使用和源码
eureka 是由 Netflix 团队开发的针对中间层服务的负载均衡器,在微服务项目中被广泛使用.相比 SLB.ALB 等负载均衡器,eureka 的服务注册是无状态的,扩展起来非常方便. 在这个系 ...
- [转]iOS学习之UINavigationController详解与使用(二)页面切换和segmentedController
转载地址:http://blog.csdn.net/totogo2010/article/details/7682433 iOS学习之UINavigationController详解与使用(一)添加U ...
- dom对象详解--document对象(二)
dom对象详解--style对象 style对象 style对象和document对象下的集合对象styleSheets有关系,styleSheets是文档中所有style对象的集合,这里讲解的 ...
- MySQL存储过程详解 mysql 存储过程(二)
mysql存储过程详解 1. 存储过程简介 我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL ...
随机推荐
- picker
滚动选择器,现支持三种选择器,通过mode来区分,分别是普通选择器,时间选择器,日期选择器,默认是普通选择器. 普通选择器:mode = selector 属性名 类型 默认值 说明 range Ar ...
- day17(tomcat的安装,HTTP)
Tomcat Tomcat是个小型服务器,由apache组织编写,转为发布java程序而写. 安装步骤: 官网:http://tomcat.apache.org/ 下载地址:http://tomcat ...
- POJ2139--Six Degrees of Cowvin Bacon(最简单Floyd)
The cows have been making movies lately, so they are ready to play a variant of the famous game &quo ...
- ubuntu下mysql远程连接
第一步: vim /etc/mysql/my.cnf找到bind-address = 127.0.0.1 注释掉这行,如:#bind-address = 127.0.0.1 ...
- noip第29课作业
1. 钢条切割 [问题描述] 一家公司购买长钢条,将其切割成短钢条出售,切割本身没有成本,长度为i的短钢条的价格为Pi.那给定一段长度为n的钢条和一个价格表Pi,求钢条的切割方案使得收益Rn最大. ...
- poj3929
题意: 如上图放置的一个圆锥,告诉你从圆锥顶的洞中流出多少体积的水,求现在水面高度.. 思路: 无聊时做的一道题,实际上就是一道高数题,重积分,可惜我高数本来也不好而且还忘光了,积了很久,而且错了很多 ...
- shell 命令之 crontab
crontab是shell命令中的定时任务: crontab -e 进入当前定时任务的vim页面 每行是一个独立的定时脚本,使用和vim的语法部署定时任务 如下图: 脚本执行周期设置 可以用下面的网页 ...
- [FMX]获取控件样式中的指定项目以便进行调节
[FMX]获取控件样式中的指定项目以便进行调节 2017-03-26 • C++ Builder.Delphi.教程 • 暂无评论 • swish •浏览 650 次 FMX 的样式丰富了我们的设计, ...
- Azure DevOps Server (TFS)中代码文件换行问题解决方案(Git)
之前写过一篇博客"探索TFS Git 库文件换行(CRLF)的处理方式",主要是针对TFVC代码库的. 下面这篇文章说明如何在TFS的Git库中处理代码换行的问题. 概述 在Azu ...
- ASP.NET微信公众号用于给指定OpenId用户发送红包
ASP.NET微信公众号用于给指定OpenId用户发送红包 微信公众号要实现对指定用户发送红包,必须指定一个存放兵发放金额的商户号,在微信商户平台里面申请商户号并获取相关参数例如发送红包所要用到的安全 ...