在机房收费系统进行过程中,听到了好多小伙伴们议论DataTable和泛型,第一次接触泛型,感觉懵懵哒,那么这两种类型有什么区别?优缺点是什么?
一、DataTable是什么?
DataTable是一个临时保存数据的网格虚拟表,它完全是在内存中的一个独立存在,包含了这张表的全部信息。使用它的对象包括DataSet和DataView。DataSet可以看做一个能移动的数据库,是有许多DataTable构成的。DataSet可以通过DataAdapter使用数据源中的数据生成,填充到每一个DataTable中。
二、泛型是什么?
官方有以下两种:
1.在程序编程中,一些包含类型参数的类型,也就是说泛型的参数只可以代表类,不能代表个别对象。(这是目前为止比较常见的定义)
2.在程序编码中一些包含参数的类。其参数可以代表类或对象等等(人们大多把这称作模板)无论使用哪种定义,泛型的参数在真正使用泛型时都必须都必须做出指明。
自己的理解:泛型是一个list<>集合,集合中的每一个元素都是一个实体,而每一个实体都相当于DataTable中的一条记录。DataTable是多条记录的集合,而List<>是多个实体的集合。
三、泛型的作用:
泛型的作用其实很简单,一般用于创建集合类,就是能够避免拆箱和装箱,提高程序的性能。它能够在编译阶段就告诉编译器,数据结构中元素的种类,既然编译器已经提前知道了元素的种类,自然就能避免拆箱和装箱的操作,从而显著提高程序的性能,比如List就直接使用String对象作为List的元素,避免使用Object对象。
四、为什么要用泛型:
(一)DataTable的缺点:
使用DataTable读取数据库中的数据时,必须要了解数据表的结构,这样会给编程带来一定的风险,一旦数据库修改,则意味着代码也必须做相应的修改,耦合性太强,不符合面向对象的思想,而且DataTable为弱实体,无法直观看出字段的数据类型。
DataTable代码分析:
'将查询到的信息显示在文本框中
<span style="font-size:18px;">txtStudentNo.Text = dt.Rows(0).Item(2) txtName.Text = dt.Rows(0).Item(3) txtSex.Text = dt.Rows(0).Item(4) txtTie.Text = dt.Rows(0).Item(5) txtGrade.Text = dt.Rows(0).Item(6) txtClass.Text = dt.Rows(0).Item(7) txtStatus.Text = dt.Rows(0).Item(11) txtExplain.Text = dt.Rows(0).Item(9) txtBalance.Text = dt.Rows(0).Item(8)</span>从上面代码中可以看出:每个文本框所对应的是具体某一行某一列的数据,是一对一的关系,数据库中的字段顺序一旦修改,就会导致文本框中显示的信息出现错误。
(二)泛型优点:
使用泛型类型可以最大限度的重用代码,保护类型的安全以及提高性能,不必了解数据库中表的结构,符合面向对象的思想,实体类型的属性是强类型,每个字段的数据类型都是已知的。
泛型代码实现:
<span style="font-size:18px;">txtStudentNo.Text = myList(0).StudentNo txtState.Text = myList(0).Status txtBalance.Text = myList(0).Cash txtDepart.Text = myList(0).Department txtGrade.Text = myList(0).Grade txtClass.Text = myList(0).Sclass txtSex.Text = myList(0).Sex txtState.Text = myList(0).Status txtExplain.Text = myList(0).Explain txtName.Text = myList(0).StudentName </span>五、DataTable转泛型:
因为我们在机房收费系统中涉及到了多个查询功能,而我们通过sqlHelper类,返回的都是DataTable类型的,所以我们需要多次进行泛型转换,为了体现代码的封装性和复用性,我们将转换的方法单独抽象出一个类放在D层,以供调用。
<span style="font-size:18px;">Imports System.Reflection '引用反射 Imports System.Collections.Generic '添加泛型的命名空间 Module ConverHelper Public Class ConvertHelper Public Shared Function ConvertToList(Of T As New)(dt As DataTable,ts As IList(Of T)) '获得T的类型 Dim type As Type = GetType(T) '定义一个临时变量 Dim strTemp As String = String.Empty '遍历表中所有行数 For Each dr As DataRow In dt.Rows '定义类型变量act获取动态创建对象T的类型 Dim act As T = If((Nothing Is Nothing),Activator.CreateInstance(Of T)(),Nothing) '引用反射表示可获得对象的所有属性组成的集合 Dim propertys As PropertyInfo() = act.[GetType]().GetProperties() '定义arry变量,接受propertys中含有的属性,并提供对属性propertys元数据访问 Dim array As PropertyInfo() = propertys Dim intCount As Integer = 0 '遍历所有对象属性 While intCount < array.Length 'lenth表示所有唯数中元素的综合 'Pr表示元素中含有的属性,并提供对数据访问 Dim pr As PropertyInfo = array(intCount) strTemp = pr.Name '列名=对象的属性名 If dt.Columns.Contains(strTemp) Then '判断此属性是否设置函数 If pr.CanWrite Then '该属性是否可写 Dim value As Object = dr(strTemp) '如果非空,则赋值给对象的属性 If value IsNot DBNull.Value Then '设置对象的属性 pr.SetValue(act,value,Nothing) End If End If End If intCount += 1 Continue While End While '添加对象到泛型集合中 ts.Add(act) Next Return ts End Function End Class</span>
在D层中调用:
'先判断dt是否为空
<span style="font-size:18px;">If dt.Rows.Count > 0 Then '将dt转换为泛型集合 list = ConverHelper.ConverHelper.ConvertToList(dt,list) Return List Else Return Nothing End If </span>六、总结: 起初看了好多别人写的关于泛型博客,但总感觉学的不理解。只有自己真正实践之后才能对这些知识点有一个大体的了解。站在岸上学不会游泳,只有实践才能获得真知!