敲三层的时候就听师傅说过泛型,只不过当时没有特别的注意。当敲用户登录窗体时,我遇到这样的问题,就是我们需要经过验证输入的信息的正误之后才能登录或者不能登录。判断时,需要返回我们从数据库中查到的信息,那么问题就来了,如何返回呢?
一开始我一直用的是DataTable返回数据的,但是当去判断的时候我不知道如何下手了,按照以往的经验,我们可以使用table.rows()或table.field(),具体的实现方法可以自己试验一下。这种方法虽然可以实现,可是里面重复的内容太多了,尤其是每次使用一个字段时还需要在数据库中数它的位置,很麻烦。因为之前听过泛型的概念,所以就开始捣鼓泛型集合了。
其实,DataTable和List的用法基本上都是一致的,两者的不同之处就在于DataTable偏向于面向过程,需要我们去一个一个的数它所在位置,而List偏向于面向对象,当我们调用它里面的数据时,只需要使用我们要的字段名称即可;相对来说,这个更加方便。下面来看一下我的DataToList类:
'/**********************************************
'类名:DataToListDAL
'命名空间:DAL
'创建时间:2015/1/7 20:33:41
'创建人:王朋波
'版本号:v1.0
'说明:将DataTable类型转换成泛型集合
'版权:Victor
'/**********************************************
Imports System.Reflection
Public Class DataToListDAL
Public Class DataToList
''' <summary>
''' 将DataTable类型转换成泛型
''' </summary>
''' <typeparam name="T">参数,转换中的参数</typeparam>
''' <param name="dt">需要转换的DataTable</param>
''' <returns>返回执行的结果,为泛型</returns>
''' <remarks></remarks>
Public Shared Function converToList(Of T As {New})(ByVal dt As DataTable) As IList(Of T)
'(Of T as {New})中的New是用来约束T的,必须有
'定义并实例化泛型集合
Dim myList As New List(Of T)
'得到实体类的类型名
Dim myType As Type = GetType(T) '此声明不知道如何使用,后边也没有用到
Dim dr As DataRow '定义行集
Dim tempName As String = String.Empty '定义一个临时变量
' 便利DataTable的所有数据行
For Each dr In dt.Rows
Dim myT As New T
Dim propertys() As PropertyInfo = myT.GetType().GetProperties() '定义属性集合
Dim pr As PropertyInfo
'遍历对象的所有属性
For Each pr In propertys
tempName = pr.Name '将属性名称赋值给临时变量
'检查DataTable是否包含此列
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(myT, value, Nothing) '在运行期间,通过反射,动态的访问一个对象的属性
End If
End If
Next
myList.Add(myT) '添加到集合
Next
Return myList '返回实体集合
End Function
End Class
End Class
然后在外观层调用数据的时候就很方便了:
'/**********************************************
'类名:FLogin
'命名空间:Facade
'创建时间:2015/1/7 20:10:36
'创建人:王朋波
'版本号:v1.0
'说明:
'版权:Victor
'/**********************************************
Imports BLL
Imports Entity
Public Class FLogin
Public Function CheckUser(ByVal enuser As En_User) As String
'实例化B层
Dim checkuserBLL As New BLogin
'实例化List,传递泛型中的值
Dim myList As New List(Of En_User)
'调用B层方法,得到B层返回的myList集合
myList = checkuserBLL.CheckUserBLL(enuser)
'对集合信息进行判定
If myList.Count > 0 Then '如果存在用户
If enuser.Password = Trim(myList(0).Password) Then '如果密码正确
Return "密码正确"
Else '如果密码不正确
Return "密码错误"
End If
Else '用户不存在
Return "用户错误"
End If
End Function
End Class
当然泛型在这里的用处还不是特别明显,等到以后的查询充值记录、上机记录等信息时的用处就更加明显了。
其实,这个过程很好的见证了我们学习的进步与提升,从一开始的面向过程,到如今的面向对象。从vb版的学生信息系统和机房收费系统中繁琐的数字段和各种重复,到如今的引入对象。用我们的亲身经历去体会这两者的区别,这样的效果和收获还是蛮大的。
有些地方可能自己还没有分析到位,而且有些代码的功能理解的程度也不深,不过通过今后的不断接触,我想这一切都不是事。当然,也希望大家能够给我指出不足之处,大家共同进步。