在机房重构的过程中,我一直用的事datatable来做返回值的记录与提取,看了大神们的博客发现这样违反了3层的结构,datatable也不是很高效,于是,就引出了泛型这个功能的探索。
WHAT?是什么
泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。各种程序设计语言和其编译器、运行环境对泛型的支持均不一样。将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。泛型类是引用类型,是堆对象,主要是引入了类型参数这个概念。--百度百科
通过自己用泛型,我的具体理解是在U层把用户传入的数据(放在实体里),然后把从D层返回一个“实体集”,用U层接,让U层直接"."出来那个实体集中的某一个要用的实体数据。这样说也挺抽象,接下来咱们慢慢聊~
WHERE?在哪用
当我们要调一个表的数据的时候,就拿datatable做例子,D层返回了一个datatable“表”,我们需要利用下面这样的代码来获取这个“表”中的数据。
'把datatable返回的“表”的第一行(0),第3列(2)取出,给txtLeastTime
txtLeastTime.Text = table.Rows(0)(2) txtMinCash.Text = table.Rows(0)(4) txtPrepareTime.Text = table.Rows(0)(3) txtRegularPrice.Text = table.Rows(0)(0) txtTemPrice.Text = table.Rows(0)(1)然,这是几条数据,如果一个表的数据有几十个,几百个呢,我们难道还有去数这条数据是第几列吗?当然不,我们不做低效率的事情。不将就就是原动力,于是,泛型也出来了。下面是泛型的取值方法:
lblStudentID.Text = mylist(0).Chr_StudentID.Trim lblSex.Text = mylist(0).Chr_Sex.Trim lblDepartment.Text = mylist(0).Chr_Department.Trim lblName.Text = mylist(0).Chr_Name.Trim lblType.Text = mylist(0).Chr_Type.Trim怎么样,是不是清新很多呢,不用去数他是在第几列,直接调出来~~
HOW?怎么用
U层:(以上机为例)
'实例化一个外观层
Dim fa As New Facade.LoginFacade
'实例化一个实体 Dim eonline As New Entity.OnLineInfo
'把用户输入的数据赋值给实体 eonline.Chr_IsUse = Label15.Text.Trim eonline.Chr_CardID = txtCardNo.Text.Trim eonline.Chr_State = Label17.Text.Trim '实例化一个泛型 Dim mylist As New List(Of Entity.OnLineInfo) '把传回来的外观层的数据用mylist 接着 mylist = fa.Online(eonline)
外观:
'声明一个方法,传实体值 eonline,返回泛型list
Public Function Online(ByVal eonline As Entity.OnLineInfo) As List(Of Entity.OnLineInfo) Dim OnlineB As New BLL.OnlineManager Dim mylist As New List(Of Entity.OnLineInfo) '声明泛型类 mylist = OnlineB.Online(eonline) Return mylist End Function
B层:
Public Class OnlineManager Public Function Online(ByVal eonline As Entity.OnLineInfo) As List(Of Entity.OnLineInfo) Dim fac As New Factory.LoginFactory Dim IUser As IDAL.ILoginUserInfo IUser = fac.CreateUserDAO Dim mylist As New List(Of Entity.OnLineInfo) '声明泛型类 mylist = IUser.Online(eonline) If mylist.Count = 0 Then MsgBox("该卡号不存在!") Return Nothing ElseIf mylist.Count = 1 And mylist(0).Chr_State = "正在上机" Then MsgBox("该卡号正在上机,请勿重复上机") Return Nothing Else Return mylist End If End Function End Class
接口层:
'上机 Function Online(ByVal eonline As Entity.OnLineInfo) As List(Of Entity.OnLineInfo)D层:
'上机 Public Function Online(ByVal eonline As Entity.OnLineInfo) As List(Of Entity.OnLineInfo) Implements IDAL.ILoginUserInfo.Online Dim sql As String '定义参数 Dim sqlParams As SqlParameter() = { New SqlParameter("@CardNo1", eonline.Chr_CardID), New SqlParameter("@LoginDate", Date.Today), New SqlParameter("@LoginTime", DateTime.Now), New SqlParameter("@Computer", Entity.LoginInfo.Computer), New SqlParameter("@IsUse", eonline.Chr_IsUse), New SqlParameter("@State", eonline.Chr_State)} '调用存储过程 sql = "PROC_Online" '实例化一个list Dim mylist As New List(Of Entity.OnLineInfo) <span style="font-family: KaiTi_GB2312;"> </span>
<pre name="code" class="vb"> '先用datatable接着D层查出来的数据,再转化为泛型
Dim dt As New DataTable dt = sqlHelper.GetDataTable(sql, CommandType.StoredProcedure, sqlParams)
'将datatable转化为泛型 mylist = ConvertHelper.ConvertHelper.convertToList(Of Entity.OnLineInfo)(dt) Return mylist End Function这里涉及到一个ConvertHelper类,这里声明了一个转化泛型的方法,代码如下:
Imports System.Reflection '引用反射 Module ConvertHelper Public Class ConvertHelper '将datatable 转化为泛型集合 Public Shared Function convertToList(Of Turn As {New})(ByVal dt As DataTable) As IList(Of Turn) '这里的new是用来约束T的 Dim mylist As New List(Of Turn) '定义最终返回的集合 Dim myType As Type = GetType(Turn) '得到实体类的类型名 Dim dr As DataRow '定义行集 Dim tempName As String = String.Empty '定义一个临时变量 '遍历DataTable的所有数据行 For Each dr In dt.Rows Dim myTurn As New Turn Dim propertys() As PropertyInfo = myTurn.GetType().GetProperties() '定义属性集合 Dim pr As PropertyInfo '遍历该对象的所有属性 For Each pr In propertys tempName = pr.Name '将属性名称赋值给临时变量 If (dt.Columns.Contains(tempName)) Then '将此属性与datatable 里的列名比较,查看datatable是否包含此属性 '判断此属性是否有Setter If (pr.CanWrite = False) Then Continue For End If Dim value As Object = dr(tempName) '定义一个对象型的变量来保存列的值 If (value.ToString <> DBNull.Value.ToString) Then '如果非空,则赋给对象的属性 pr.SetValue(myTurn, value, Nothing) '在运行期间,通过反射,动态的访问一个对象的属性 End If End If Next mylist.Add(myTurn) '添加到集合 Next Return mylist '返回实体集合 End Function End Class End Module
这就是泛型的实现,利用泛型,我们不仅让3层更加完美,也提高了我们编程的效率,不将就就是原动力,不做代码的搬运工,用自己的大脑开拓出一片新视野。