前言
大家是不是经常会跑到楼下收快递小伙给送来的快递,你的快递一般是不是都封装到一个箱子里面,其实我这次给大家简述的泛型与送快递的小哥是一个道理ps(突然间让我想到我拆快递的样子了,哈哈)
内容
什么是泛型
定义:泛型是具有占位符(类型参数)的类,结构,接口和方法,这些占位符是类,结构,接口,方法所存储或使用的一个或者多个类型的占位符,泛型集合类可以将类型参数用作他所存储的对象的类型的占位符,类型参数作为其字段和其方法的参数
当大家看完定义之后可能会感觉很蒙,这都是啥跟啥啊,我跟大家用大白话解释一下吧
泛型其实就是对一些类型参数进行返回,返回值的类型,而类型参数一般都是字段的类型和方法,当我们在声明泛型为什么类型则接受就是什么类型,就像前言里面的快递小哥送快递一样,是一个道理,快递公司需要把我们的商品进行归类,也就是我们泛型中所定义的类型,我们接受的时候当然也要想通的类型
为什么要泛型而不建议用datatable
datatable与泛型用法基本都是一致,两者不同之处在于datatable面向的过程,而泛型面向的是对象,当我们调用数据的时候,我们只需要知道字段的名称即可,不用datatable的原因是他与数据库的耦合性太大,需要知道每个字段在数据库中的索引值,这样很不方便,我们需要不断的去查看数据库,并且泛型是object的类型,可以灵活的转换,不用装箱和拆箱,(装箱和拆箱的意思是可以通过之类型的任何值互相转换),方便很多的
泛型是对对象的填充而datatable是对数据的填充这是他们最大的区别,ps自我认为
附加给大家一张图
实体与泛型
实体是一个个的传递数据,而泛型则是把实体放到自己的木桶里,其实就像我们的快递小哥一样,把我们的商品放到一个箱子里面,并不是把一个人东西分放到不同的地方,如果这样做会导致丢失东西,因为太零散,需要送的东西太多
其实泛型传递与实体传递查不了不多,代码也差多,只是定义不同摆了,另外就是把实体放大到泛型里面了
代码
希望可以帮助大家
Imports System.Collections.Generic '增加泛型的命名空间
Imports System.Reflection '引用反射 为了使用Propertyinfo
Module ConverHelper
Public Class ConvertHelper
'convertToList(Of T As {New})这里的new是用来约束T的,必须有,否则new T的时候会出错
'在C#中new约束用的是where来给T加约束
' 其中的T表示泛型,是使用时可以使用任何类型的数据型进行替换。,所以这句话的意思就是让datatable转化为泛型
Public Shared Function convertToList(Of T As {New})(ByVal dt As DataTable) As IList(Of T)
'
'定义mylist集合,接收datatable传过来的结果,而mylist的类型是T参数
Dim mylist As New List(Of T) '定义最终返回的集合
'GetType作用是:返回指定类型的Type对象,type对象提供有关类型的信息,如类型的属性,方法,事件
Dim myType As Type = GetType(T) '得到实体类的类型名
Dim dr As DataRow '定义datatable的行
Dim tempName As String = String.Empty '定义一个临时变量,string.Empty表示的是空字符串,只读属性
'遍历datatable中的所有数据
For Each dr In dt.Rows
'定义一个实体类的对象
Dim MyT As New T
'引用反射表示可获得对象的所有属性组成的集合
'.GetProperties()获取当前统type的属性,定义一个数组,用来存储实体的属性
Dim propertys() As PropertyInfo = MyT.GetType().GetProperties()
'定义pr变量, 接收propertyinfo中的所有属性, 并提供对属性propertys元素数据访问
Dim pr As PropertyInfo
'遍历取得属性的名字,然后将一行的值传到List中
' ********************************************************************************
'遍历该对象的所有属性
For Each pr In propertys
'将属性名称复制给临时变量
tempName = pr.Name
'列明等于对象属性名
'将此属性与datatable里的名列比较,查看datatable是否包含此属性
If (dt.Columns.Contains(tempName)) Then
'判断此属性时候设置函数
If pr.CanWrite = False Then
Continue For '该属性是否可读
End If
'定义一个对象型的变量来保存列的值
Dim value As Object = dr(tempName)
'如果为空则赋值给对象的属性MyT
If (value.ToString <> DBNull.Value.ToString) Then
'在运行期间,通过反射,动态的访问一个对象的属性
'value的值给了MyT,nothing代表的是索引,但是因为是非索引的属性所以就用nothing
pr.SetValue(MyT, value, Nothing)
End If
End If
Next
mylist.Add(MyT) '添加到集合,把结果添加到泛型中,MyT也就是T的类型
Next
Return mylist ’返回实体集合
End Function
End Class
End Module