.NET泛型解析(上)
【1】:泛型介绍
泛型是C#2.0中一个重要的新特性,泛型是CLR和编程语言提供的一种特殊机制,它支持另一种形式的代码重用。泛型通常用与集合以及作用于集合的方法一起使用,当然也可以单独使用.
一般情况下,创建泛型类的过程为:从一个现有的具体类开始,逐一将每个类型更改为类型参数,直至达到通用化和可用性的最佳平衡。 创建您自己的泛型类时,需要特别注意以下事项:
将哪些类型通用化为类型参数。
通常,能够参数化的类型越多,代码就会变得越灵活,重用性就越好。 但是,太多的通用化会使其他开发人员难以阅读或理解代码。
如果存在约束,应对类型参数应用什么约束
一条有用的规则是,应用尽可能最多的约束,但仍使您能够处理必须处理的类型。 例如,如果您知道您的泛型类仅用于引用类型,则应用类约束。 这可以防止您的类被意外地用于值类型,并允许您对 T 使用 as 运算符以及检查空值。
是否将泛型行为分解为基类和子类。
由于泛型类可以作为基类使用,此处适用的设计注意事项与非泛型类相同。 请参见本主题后面有关从泛型基类继承的规则。
是否实现一个或多个泛型接口。
例如,如果您设计一个类,该类将用于创建基于泛型的集合中的项,则可能必须实现一个接口,如 IComparable,其中 T 是您的类的类型。
【2】:泛型的表示方式
System.Collections.Generic 命名空间包含定义泛型集合的接口和类,泛型集合允许用户创建强类型集合,它能提供比非泛型强类型集合更好的类型安全性和性能。创建泛型类的过程为:从一个现有的具体类开始,逐一将每个类型更改为类型参数,直至达到通用化和可用性的最佳平衡
【3】:泛型的好处
public List<TrainingUser>GetTrainingUser(string userId)
{
DataTable dt =
SqliteHelper.ExecuteDataset(System.Data.CommandType.Text,
@"
SELECT DISTINCT UserId,TrainingId FROM TRAININGUSER AS TU
INNER JOIN [USER] AS U
ON U.ID = TU.USERID
JOIN [TRAINING] AS T
ON T.ID = TU.TRAININGID
WHERE U.ID = '"+userId+"' AND T.ENDTIME > DATETIME('now', 'localtime') AND T.StartTime <= DATETIME('now', 'localtime') ;").Tables[];
return DataTableToList(dt);
} private List<TrainingUser> DataTableToList(DataTabledt)
{
List<TrainingUser> list = new List<TrainingUser>();
if(dt. Rows.Count > )
{
foreach (DataRow row in dt .Rows)
{
TrainingUser trainingUser = new TrainingUser();
if(row["UserId" ] != null)
{
trainingUser .UserId = row["UserId"].ToString();
}
if(row["TrainingId" ] != null)
{
trainingUser.TrainingId = row["TrainingId"].ToString();
}
list.Add(trainingUser);
}
}
return list;
}
public static List<T> ToList1<T>(DataTable dt) whereT : class, new()
{
var prlist =new List<PropertyInfo>();
Type type = typeof(T);
Array.ForEach(
type.GetProperties(),
p =>
{
if(dt.Columns.IndexOf(p.Name) !=-)
{
prlist.Add(p);
}
});
var oblist = new List<T>(); // System.Data.SqlTypes.
foreach(DataRow row in dt.Rows)
{
var ob = new T();
prlist.ForEach(
p =>
{
if(row[p.Name] != DBNull.Value)
{
p.SetValue(ob, row[p.Name], null);
}
});
oblist.Add(ob);
} return oblist;
}
在上面的这个方法中,我们定义了一个泛型方法,内部实现中是使用了反射的原理,将DataTable转换为了List(反射后续随笔中总结,此处只关注泛型部分即可),我们定义了一个静态的返回值为List<T> ,前面我们说过 T : 代表任意类型(枚举除外),ToList1<T>,说明我们在调用这个方法的时候,同时要赋予方法名一个类型值,这个类型要和它的返回值类型一致(泛型是类型安全的),Where : 用于限制T的条件 ,例如 where T : class,new() 表示 T 只能是一个类,或者一个类型对象,那么我们在调用的时候就可以这样来
public List<TrainingUser>GetTrainingIdByUserId(string userId)
{
List<TrainingUser> trainingUserList = DataTableHelper.ToList1<TrainingUser>(
SqliteHelper.ExecuteDataset(System.Data.CommandType.Text,
@"
SELECT DISTINCT UserId,TrainingId FROM TRAININGUSER AS TU
INNER JOIN [USER] AS U
ON U.ID = TU.USERID
JOIN [TRAINING] AS T
ON T.ID = TU.TRAININGID
WHERE U.ID = '"+ userId +"' AND T.ENDTIME > DATETIME('now', 'localtime') AND T.StartTime <= DATETIME('now', 'localtime') ;").Tables[]);
return trainingUserList ;
}
private static void ListTest()
{
List<int>list = new List<int>();
for(inti = ; i < ; i++)
{
list.Add(i);
int a = list[i];
}
list =null;
}
private static void ArrListTest()
{
ArrayList arr = new ArrayList();
for(inti = ; i <; i++)
{
arr.Add(i);
int s = (int)arr[i];
}
arr = null;
} Stopwatch sw = new Stopwatch();
sw.Start();
ListTest();
Console.WriteLine(" 使用泛型List执行值类型方法历时 : "+ sw.Elapsed.ToString());
sw.Stop(); Stopwatch sw1 = new Stopwatch();
sw1.Start();
ArrListTest();
Console.WriteLine(" 使用非泛型ArrayList执行值类型方法历时 : "+ sw1.Elapsed.ToString());
sw1.Stop();
Console.ReadLine();
通过循环 100 来比较,结果为 :

我们可以看到非泛型的时间要比泛型的时间多出0.0000523秒,泛型比非泛型的时间要多出一些, 那么我们将数值改动一下改为循环 1000次.得出结果为 :





将一个泛型算法应用于一个具体的类型时,编译器和CLR能理解开发人员的意图,并保证只有与指定数据类型兼容的对象才能随同算法使用,若试图使用不兼容类型的一个对象,会造成编译时错误,或者运行时抛出异常
此篇至此,下篇主要知识点 :
1、泛型方法2、泛型接口3、泛型约束(主要约束,次要约束,构造器约束)4、泛型类型转型5、泛型委托6、泛型和反射7、泛型和属性
温馨提示 : 知识点重温,不断总结,思考, 也是一种阶段性提高,希望能帮到在读的你.
.NET泛型解析(上)的更多相关文章
- WCF 已知类型和泛型解析程序 KnownType
数据协定继承 已知类型和泛型解析程序 Juval Lowy 下载代码示例 自首次发布以来,Windows Communication Foundation (WCF) 开发人员便必须处理数据协定继承方 ...
- Java泛型解析(04):约束和局限性
Java泛型解析(04):约束和局限性 前两节.认识和学习了泛型的限定以及通配符.刚開始学习的人可能须要一些时间去体会到泛型程序设计的优点和力量,特别是想成为库程序猿的同学就须要下 ...
- android多线程-AsyncTask之工作原理深入解析(上)
关联文章: Android 多线程之HandlerThread 完全详解 Android 多线程之IntentService 完全详解 android多线程-AsyncTask之工作原理深入解析(上) ...
- Java泛型解析(01):认识泛型
Java泛型解析(01):认识泛型 What Java从1.0版本号到如今的8.中间Java5中发生了一个非常重要的变化,那就是泛型机制的引入.Java5引入了泛型,主要还是为了满足在199 ...
- Java泛型解析(02):通配符限定
Java泛型解析(02):通配符限定 考虑一个这种场景.计算数组中的最大元素. [code01] public class ArrayUtil { public static <T&g ...
- Java泛型解析(03):虚拟机运行泛型代码
Java泛型解析(03):虚拟机运行泛型代码 Java虚拟机是不存在泛型类型对象的,全部的对象都属于普通类,甚至在泛型实现的早起版本号中,可以将使用泛型的程序编译为在1.0虚拟机上可以执行的 ...
- 使用GSON和泛型解析约定格式的JSON串(转)
时间紧张,先记一笔,后续优化与完善. 解决的问题: 使用GSON和泛型解析约定格式的JSON串. 背景介绍: 1.使用GSON来进行JSON串与java代码的互相转换. 2.JSON的格式如下三种: ...
- js上传文件带参数,并且,返回给前台文件路径,解析上传的xml文件,存储到数据库中
ajaxfileupload.js jQuery.extend({ createUploadIframe: function(id, uri) { //create frame var frameId ...
- django 解析上传xls文件
1.解析上传数据 class DataUploadAPIView(APIView): # authentication_classes = (JSONWebTokenAuthentication, S ...
随机推荐
- “System.Runtime.InteropServices.COMException (0x80070422): 无法启动服务”解决方法
应用程序中发生了无法处理的异常.如果单击“退出”,应用程序将立即关闭.无法启动服务,原因可能是已被禁用或其相关联设备没有启动.(异常来自HRESULT:0X80070422).点击详细内容:有关调用实 ...
- Java集合转有类型的数组之toArray(T[] a)
在java变成中慎用强制类型转换,尽量使用类自带的转换函数或泛型.先看一行代码 错误方法: String[] array= (String[]) list.toArray(); 如果list中存放的是 ...
- Sybase数据库常用sql语言
Sybase数据库常用sql语言 1,表备份: --table_name1:需要备份的表; table_name2:备份后的表 SELECT * into table_name2 from table ...
- 20145301《网络对抗》Exp2 后门原理与实践
20145301<网络对抗>Exp2 后门原理与实践 基础问题回答 例举你能想到的一个后门进入到你系统中的可能方式? 系统或者某些软件自身留下的后门. 钓鱼网站等非正规网站上捆绑下载 例举 ...
- 20155201 实验一《Java开发环境的熟悉》实验报告
20155201 实验一<Java开发环境的熟悉>实验报告 一.实验内容 1.使用JDK编译.运行简单的Java程序 2.使用IDEA 编辑.编译.运行.调试Java程序. 二.练习 题目 ...
- SQL优化:清理生产环境中已失效字段基本步骤
1.统计相应字段的数据情况(如:几年没更新,无数据等情况) 2.确认产品逻辑已无效(产品经理邮件确认) 3.数据备份 4.将数据清空(置为0或空) 5.测试环境中删除引用页面 6.修改定时程序,存储过 ...
- Spring Boot 之注解@Component @ConfigurationProperties(prefix = "sms")
从spring-boot开始,已经支持yml文件形式的配置,@ConfigurationProperties的大致作用就是通过它可以把properties或者yml配置直接转成对象 例如: 配置文件: ...
- BZOJ 4013 【HNOI2015】 实验比较
题目链接:实验比较 如果我们把相等关系全部缩起来的话,这道题给出的小于关系如果有环,那么就是不合法的,否则就构成了一片森林. 定义等于号连起来的所有变量看做一个块. 然后我们就可以令\(f_{i,j} ...
- 1003: [ZJOI2006]物流运输 最短路+dp
https://www.lydsy.com/JudgeOnline/problem.php?id=1003 数据范围很小,怎么瞎搞都行,n方dp,然后跑出最短路暴力转移,需要注意的是不能使用的可能有多 ...
- uva-11021-全概率公式
https://vjudge.net/problem/UVA-11021 有n个球,每只的存活期都是1天,他死之后有pi的概率产生i个球(0<=i<n),一开始有k个球,问m天之后所有球都 ...