泛型

前言:

在机房重构的过程,以学生查看余额为例功能为例,我刚开始会从D层传回一个datable类型的表,一直传到了U层,然后再根据datable的行号和列号往各个文本框中赋值,这样我就必须要知道数据库中字段的结构顺序,这样U层和D层之间的耦合大大增大,这当然不是我们想要的了,还有一点是有时我想返回一个datatable类型的表和一个Boolean类型,如何同时返回多种类型的数据?这就引来了泛型。


泛型了解:

泛型其实就是一个整理箱,里面可以存放各种类型的物品,看了雪芬的博客,把泛型比喻为我们取来的快递箱子,我们想一下,当我们买了面膜,一个精致的盒子里面放着好多张面膜,这样只通过一个盒子就可以把所有的面膜取回来,通过盒子把买来的额物品封装到一了一起,而这个盒子就相当于我们泛型中定义的List,面膜就是List中的元素。

下面是数组,集合,泛型的比较:

数组

只能放定义类型的元素,不会自动增大,取出时不用做类型转换

集合

可放任意类型的元素,会自动增大,取出时要做类型转换

泛型

 

只能放定义类型的元素,会自动增大,取出时不用做类型转换


泛型中<List(Of T)>,T就是一个要引用的实体,对象,就是List的一个参数。一个泛型里可以包含同一个类型的很多实体。下图详细地描述了如何将datatable类型的数据转化为List:




泛型的使用方法:

1.定义泛型:

Dim list As New List(Of T)

2.使用泛型

我们从数据库查询出来的数据是datatable类型的,如何将datatable类型的数据转化为List类型呢?这时我们需要定义一个把datable类型的数据转化为List类型的类:

Imports System.Reflection
'实现datatable对实体的转换功能
Public Class ModelHelper
    Public Shared Function convertTolist(Of T As {New})(ByVal dt As DataTable) As IList(Of t)
        '获得T的类型
        Dim type As Type = GetType(T)
        Dim ts As New List(Of 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()
            '定义array变量,接收propertys中含有的属性,并提供对属性propertys元数据访问    
            Dim array As PropertyInfo() = propertys
            Dim intCount As Integer = 0
            '遍历所有对象属性    
            While intCount < array.Length 'length表示所有维数中元素的总和    
                '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


方法convertTolist,是把DataTable类型的dt转化为T类型的。在学生查看余额中,通过输入的卡号Cardno得到了一条记录datatable类型的dt,然后把dt中对应的字段值放到显示余额信息的CardInfo实体中,这样CardInfo就作为List的一个元素返回。

Public Shared Function convertTolist(Of T As {New})(ByVal dt As DataTable) As IList(Of t)


在这里需要注意两点:

1).实体的属性名称必须和数据表字段的名称一致。因为它会去判断如果过数据库中字段包含实体中属性,就会把字段所对应的值赋给属性,如果实体属性名称和数据库字段名称不一致,就会返回Null值。

 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

(2)类型转换

当在执行的出了如下的错误:类型System.String的对象无法转化为类型“System.Char”原来是因为我把所有数据都转为了string的类型,而在实体CardInfo中我定义的却是Char类型。这样就会出现如下的错误。

解决办法:把实体中属性改为string类型即可。


3.读取泛型中的值:

list(0)代表的是List中第一条记录,这样我们直接通过实体的属性对UI层的textbox进行赋值就可以,而不需要知道数据库中的字段信息。下面就是把泛型中第0条记录CardInfo中的属性读取出来。

            txtSid.Text = list(0).studentNo
            txtName.Text = list(0).studentName
            txtSex.Text = list(0).sex
            txtDepartment.Text = list(0).department
            txtGrade.Text = list(0).grade
            txtClass.Text = list(0).classNo
            txtState.Text = list(0).Status
            txtBalance.Text = list(0).Status


总结:

通过泛型来封装数据,把数据传到UI层,实际泛型里存放的很多的实体,而泛型只是个桶,通过泛型很好地保证了七层结构,使得各层之间的耦合度极度降低,但是使用Datatable类型的话,在UI层就必须要知道数据库的结构,打破了七层的结构。

刚开始我一直是用的Datatable,后来听雪芬说要先了解泛型,所以我就试着在网上搜了很多泛型的使用方法,当然遇到了很多的问题,但是在调错的过程中就理解了,现在我们的目的不是实现功能,而是想应该怎样减少代码,增强代码的可复用,以及系统的扩展性,灵活性,使得系统达到最优,这样学起来就会很有意思,以前接触到的很多但是还不理解的东西(如设计模式,存储过程,视图等)都是我们学习的机会。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 26
    评论
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

诗琪小姐姐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值