.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 ...
随机推荐
- 使用docker创建aosp编译环境
如果只需要编译一个版本的aosp,那么如果在主机上架建环境即可,可写的程序如果要在各个aosp版本中编译,那在主机上架建多个aosp编译环境可以会比较麻烦,github上找到一个openstf用doc ...
- 【转】微信jssdk录音功能开发记录
转自:http://www.cnblogs.com/liujunyang/p/4962423.html#undefined 0.需求描述 在微信浏览器内打开的页面,制作一个按钮,用户按住按钮后开始录音 ...
- zabbix-2.4.7环境部署与初始化安装
一.zabbix简介: zabbix的特点: - 安装与配置简单,学习成本低 - 支持多语言(包括中文) - 免费开源 - 自动发现服务器与网络设备 - 分布式监视以及WEB集中管理功能 - 可以无a ...
- 20155201 2016-2017-2 《Java程序设计》第八周学习总结
20155201 2016-2017-2 <Java程序设计>第八周学习总结 教材学习内容总结 第十四章 NIO与NIO2 相对于串流输入/输出使用InputSteam,OutputStr ...
- pickle & cPickle ValueError: unsupported pickle protocol: 3
pickle and cPickle pickle和cPickle是python对象的转储文件,保存的是python对象 他们分别是python2和python3的对应部分,建议引入的时候采用以下方法 ...
- Codeforces Round #390 (Div. 2) D. Fedor and coupons(区间最大交集+优先队列)
http://codeforces.com/contest/754/problem/D 题意: 给定几组区间,找k组区间,使得它们的公共交集最大. 思路: 在k组区间中,它们的公共交集=k组区间中右端 ...
- Template Method(模板方法)
意图: 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.TemplateMethod 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 适用性: 一次性实现一个算法的不变的部分, ...
- Rails 5 Test Prescriptions 第10章 Unit_Testing JavaScript(新工具,learn曲线太陡峭,pass)
对Js的单元测试是一个大的题目.作者认为Ruby的相关测试工具比Js的测试工具更灵活 大多数Js代码最终是关于响应用户的行为和改变DOM中的元素 没有什么javascript的知识点.前两节用了几个新 ...
- Android------个人项目(歆语计算器)
歆语混合计算器,触手可及,畅享运算,欢迎使用,支持4则混合运算, 可以同时加,减,乘,除,前提是计算格式要输入正确,提供便利的计算功能. apk下载地址: http://shouji.baidu.co ...
- 过滤器系列(三)—— RSQF
这个过滤器本身是一篇论文中提出的过滤器的简化版本,去掉了计数功能,我觉得简化版本应用的可能也很广,专门写一篇简化版本的RSQF.RSQF全称是rank-and-select based filter, ...