C# 泛型使用笔记
泛型的基本概念我就不在这重复了,不了解的同学请自行百度。
我主要写下我在项目中要到的泛型实例。献丑了.....有什么不好或不对的地方大家尽可评论留言。
为什么要用泛型?
通过使用泛型,我们可以极大地提高代码的重用度,同时还可以获得强类型的支持,避免了隐式的装箱、拆箱,在一定程度上提升了应用程序的性能。
作为一个想法的程序猿,不能仅仅只会"复制 粘贴"。
代码的封装、重用是可以大大提高你的效率,对于之后代码的修改及二次开发很有帮助。
当然使你"看起来"很NB,增加自己的成就感。
使用泛型实例
我在项目用到泛型的地方主要是用在封装获取数据的时候。
之前获取一个Model PR_Form 的数据我是这样写的。
public partial class PR_Form
{
public PR_Form()
{}
public long FM_ID {get;set;}
public string PR_NO {get;set;}
}
//根据FM_ID获取PR_Form数据
public PR_Form GetPRForms(long FM_ID)
{
//构造 where条件
string searchCriteria = "where FM_ID=@FM_ID";
//参数
SqlParameter[] sqlParams = { new SqlParameter("@FM_ID", FM_ID) };
PR_Form _form = new PR_Form();
//拼接sql语句
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.Append(@"select [FM_ID],
[PR_NO] from PR_Form ");
sqlBuilder.Append(searchCriteria);
//查询数据 注:这里用dataset不是很好,哈哈
DataSet ds = DbHelperSQL.Query(sqlBuilder.ToString(), sqlParams);
//如果查到数据给_form 赋值
if (ds.Tables[].Rows.Count > )
{
//将记录映射为实例
for (int i = ; i < ds.Tables[].Rows.Count; i++)
{
if (null != ds.Tables[].Rows[i]["FM_ID"])
{
_form.FM_ID = long.Parse(ds.Tables[].Rows[i]["FM_ID"].ToString());
} if (null != ds.Tables[].Rows[i]["PR_NO"])
{
_form.PR_NO = ds.Tables[].Rows[i]["PR_NO"].ToString();
}
}
} return _form;
}
上面代码可以优化的地方很多。
首先我这边去掉了很多 PR_Form 属性,实际应用中PR_Form 的数据不止这几个。
那么我每次在读取到数据的时候 “ 将记录映射为实例”是不是可以封装一下?方便之后重用?
当然可以
我们封装一个通用的 DataRow返回相应类的方法
// 将记录映射为实例
private T ConvertToModel<T>(DataRow dr) where T : class, new()//泛型的约束。class:使用此方法的必须是一个类,new():必须有空参数的构造函数
{
T o = new T();
//获取指定类型的公共属性
PropertyInfo[] propertys = o.GetType().GetProperties();
foreach (PropertyInfo p in propertys)
{
try
{
// 判断此属性是否有Setter
if (!p.CanWrite)
continue; object value = dr[p.Name];
if (value != DBNull.Value)
p.SetValue(o, dr[p.Name], null); }
catch{}
} return o;
}
然后我们的代码就变成这样了。
//根据FM_ID获取PR_Form数据
public PR_Form GetPRForms(long FM_ID)
{
//构造 where条件
string searchCriteria = "where FM_ID=@FM_ID";
//参数
SqlParameter[] sqlParams = { new SqlParameter("@FM_ID", FM_ID) };
PR_Form _form = new PR_Form();
//拼接sql语句
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.Append(@"select [FM_ID],
[PR_NO]
from PR_Form ");
sqlBuilder.Append(searchCriteria);
//查询数据 注:这里用dataset不是很好,哈哈
DataSet ds = DbHelperSQL.Query(sqlBuilder.ToString(), sqlParams);
//如果查到数据给_form 复制
if (ds.Tables[].Rows.Count > )
{
_form = ConvertToModel(ds.Tables[].Rows[]);
} return _form;
}
博主:这样写之后我们不管 DataRow增加任何列都不用修改代码。
博友:博主你在扯淡么? DataRow的列都是sql语句决定,如果数据库增加列,我还是要修改Model,和sql查询语句!
博主:哈哈,是这样的。那我们继续封装.....接下来我们通过类的属性封装一下查询语句。
博友:别别别。。。一步到位可以么? 如果我要查询其他Model的数据呢?这个也一起封装了岂不是更好?
博主:OK。长话短说
既然我们要通过类来生成Sql语句,那就要对Model类进行一些配置,比如说类对应的表名、表的主键、要查询的字段等。。。
我们根据相应的配置来生成sql语句。
首先我们要对model 类进行修改。给model类添加自定义属性
[Table(TableName = "PR_Form", PrimaryKey = "FM_ID ", SortType = , SearchFields = "*")]
//TableName:表示对应数据库的表名,PrimaryKey:表示表的主键,SearchFields:查询字段(如id,name....),我这里省事直接写了*
public partial class PR_Form
{
public PR_Form()
{}
public long FM_ID {get;set;}
public string PR_NO {get;set;}
}
添加接收自定义属性的类TableAttribute
/// <summary>
/// 数据库表属性
/// </summary>
public class TableAttribute : Attribute
{
public TableAttribute()
{
} /// <summary>
/// 实例化
/// </summary>
/// <param name="tablename">表名或视图名 视图名要有对应类存在</param>
public TableAttribute(string tablename)
{
_tablename = tablename;
} /// <summary>
/// 实例化
/// </summary>
/// <param name="tablename">表名或视图名 视图名要有对应类存在</param>
/// <param name="primaryKey">主键 默认值:Id</param>
public TableAttribute(string tablename, string primaryKey)
{
_tablename = tablename;
_primaryKey = primaryKey;
} private string _primaryKey = "Id";
/// <summary>
/// 主键 默认值:Id
/// </summary>
public string PrimaryKey { get { return _primaryKey; } set { _primaryKey = value; } } private string _tablename = "";
/// <summary>
/// 表名或视图名 视图名要有对应类存在
/// </summary>
public string TableName { get { return _tablename; } set { _tablename = value; } } private int _sortType = ;
/// <summary>
/// 排序类型 查询时用到 默认值:-1(默认排序), 0(ASC) ,1(DESC)
/// </summary>
public int SortType { get { return _sortType; } set { _sortType = value; } } private string _sortFields = "Id";
/// <summary>
/// 排序字段 查询时用到 SortType>0时生效 默认值:Id
/// </summary>
public string SortFields { get { return _sortFields; } set { _sortFields = value; } } private string _SearchFields = "*";
/// <summary>
/// SearchFileds 查询时用到 默认值:*
/// </summary>
public string SearchFields { get { return _SearchFields; } set { _SearchFields = value; } } private int _Top = ;
/// <summary>
/// Top多少数据 查询时用到 默认值:0 无限制
/// </summary>
public int Top { get { return _Top; } set { _Top = value; } } private string _ConnectionString = "ConnectionString";
/// <summary>
/// 连接字符串 默认为:ConnectionString
/// </summary>
public string ConnectionString { get { return _ConnectionString; } set { _ConnectionString = value; } } }
获取model PR_Form的自定义属性这样写。
object[] objAttrs = new PR_Form().GetType().GetCustomAttributes(typeof(TableAttribute), true);
OK,准备工作就绪。
最后结果
public T GetModel<T>(long FM_ID) where T : class, new()
{
T obj = new T();
//获取 Model 配置
object[] objAttrs = new T().GetType().GetCustomAttributes(typeof(TableAttribute), true);
if (objAttrs.Length > )
{
TableAttribute attr = objAttrs[] as TableAttribute;
if (attr != null)
{
//参数
SqlParameter[] sqlParams = { new SqlParameter("@FM_ID", FM_ID) };
//构造 sql条件
string strSQL = "select {0} from {1} where {2}=@FM_ID" ";
strSQL = string.Format(strSQL, attr.SearchFields, attr.TableName, attr.PrimaryKey); //查询数据 注:这里用dataset不是很好,哈哈
DataSet ds = DbHelperSQL.Query(strSQL, sqlParams);
if (ds.Tables[] == null || ds.Tables[].Rows.Count < )
return null;
//将记录映射为实例
obj=ConvertToModel<T>(dt.Rows[]); return obj;
}
}
return null; }
调用代码
var _Form= bllbase.GetModel<PR_Form>( FormId);
献丑了。这是我第一次在项目中使用泛型,大神莫笑我啊。
那里不对的地方,请打加指出。
C# 泛型使用笔记的更多相关文章
- 《CLR.via.C#第三版》第二部分第12章节 泛型 读书笔记(六)
终于讲到泛型了.当初看到这个书名,最想看的就是作者对泛型,委托,反射这些概念的理解.很多人对泛型的理解停留在泛型集合上,刚开始我也是,随着项目越做越多,对待泛型的认识也越来越深刻. 泛型的概念:泛型是 ...
- 【09-03】java泛型学习笔记
静态方法的泛型 /** * @description 静态方法的泛型无法使用类定义的泛型,因为类在实例化时才确定具体的泛型类,因此静态方法要使用泛型需要使用泛型方法的方式 */ public clas ...
- 《C#高级编程(第六版)》泛型学习笔记(一):泛型优点和特性 (转载)
原文出处:http://www.cnblogs.com/xun126/archive/2011/01/13/1933838.html 泛型是CLR 2.0的一个新特性,在CLR 1.0中,要创建一个灵 ...
- Java泛型学习笔记 - (七)浅析泛型中通配符的使用
一.基本概念:在学习Java泛型的过程中, 通配符是较难理解的一部分. 主要有以下三类:1. 无边界的通配符(Unbounded Wildcards), 就是<?>, 比如List< ...
- Java泛型学习笔记 - (六)泛型的继承
在学习继承的时候, 我们已经知道可以将一个子类的对象赋值给其父类的对象, 也就是父类引用指向子类对象, 如: Object obj = new Integer(10); 这其实就是面向对象编程中的is ...
- Java泛型学习笔记 - (五)泛型接口
所谓泛型接口, 类似于泛型类, 就是将泛型定义在接口上, 其格式如下: public interface 接口名<类型参数>如: interface Inter<T> { pu ...
- Java泛型学习笔记 - (四)有界类型参数
1. 当我们希望对泛型的类型参数的类型进行限制的时候(好拗口), 我们就应该使用有界类型参数(Bounded Type Parameters). 有界类型参数使用extends关键字后面接上边界类型来 ...
- Java泛型学习笔记 - (三)泛型方法
泛型方法其实和泛型类差不多, 就是把泛型定义在方法上, 格式大概就是: public <类型参数> 返回类型 方法名(泛型类型 变量名) {...}泛型方法又分为动态方法和静态方法,:1. ...
- Java泛型学习笔记 - (二)泛型类
1. 我们先写一个没有泛型的类Box: public class Box { private Object obj; public Box() {} public Object getObj() { ...
- Java泛型学习笔记 - (一)泛型的介绍
一.什么是泛型:泛型的作用是用来规定一个类, 接口或方法所能接受的数据的类型. 就像在声明方法时指定参数一样, 我们在声明一个类, 接口或方法时, 也可以指定其"类型参数", 也就 ...
随机推荐
- kali linux之steghide
Steghide Linux 命令行隐写工具 Steghide是一款开源的隐写术软件,它可以让你在一张图片或者音频文件中隐藏你的秘密信息,而且你不会注意到图片或音频文件发生了任何的改变.而且,你的秘 ...
- 从一个bug谈谈psqlodbc游标的一点认识
本文源于最近修正的一个关于psqlodbc的bug,该bug在近期的psqlodbc的git上也有人提交了修正. 关于该bug的修正代码可以看这里: https://git.postgresql.or ...
- Description &&debugDescription && runtime(debug模式下调试model)
description 在开发过程中, 往往会有很多的model来装载属性. 而在开发期间经常会进行调试查看model里的属性值是否正确. 那么问题来了, 在objective-c里使用NSLog(& ...
- C#-一维数组——★★冒泡排序★★
////★★★★★冒泡排序 ; i < a - ; i++) { ; j < a; j++) { if (age[i] < age[j]) { int zhong = age[i]; ...
- FCN详解
转载自:https://www.cnblogs.com/gujianhan/p/6030639.html 论文地址:https://arxiv.org/pdf/1411.4038v1.pdf 背景 C ...
- 汉诺塔的python 动画演示
1.简介 古代有一座汉诺塔,塔内有3个座A.B.C,A座上有n个盘子,盘子大小不等,大的在下,小的在上,如图所示.有一个和尚想把这n个盘子从A座移到C座,但每次只能移动一个盘子,并且自移动过程中,3个 ...
- 微信内置的浏览器window.location.href 跳转不兼容问题
1.不兼容苹果手机---->>>>使用模拟触发a标签 <a id="alink" href="http://www.baidu.com&qu ...
- Linux系统编程:文件I/O编程
文件I/O操作在Linux编程时是经常会使用到的一个内容,通常可以把比较大的数据写到一个文件中来进行存储或者与其他进程进行数据传输,这样比写到一个全局数组或指针参数来实现还要方便好多. 一.文件常用操 ...
- BigDecimal加减乘除运算(转)
java.math.BigDecimal.BigDecimal一共有4个够造方法,让我先来看看其中的两种用法: 第一种:BigDecimal(double val) Translates a doub ...
- Java反射机制的浅显理解(这篇文章还没写好,留个草稿给自己看的)
目前只是有一个大概的理解,先把自己感觉容易立即的概念放这里,等以后结合实际工作理解深刻了再来补充. 一.什么是Java反射机制?(多种定义) 1. JAVA反射机制是在运行状态中,对于任意一个类,都能 ...