【机房重构】——泛型

          


一、泛型概念


泛型是具有占位符(类型参数)的类、结构、接口和方法,这些占位符是类、接口和方法所存储或使用的一个或多个类型的占位符。泛型集合类可以将类型参数用作它所存储的对象的类型的占位符;类型参数作为其字段的类型和器方法的参数类型出现。


二、机房重构中的泛型


我们开始重构时在SQLHelper中返回的是一张表也就是DataTable类型的,然后再一直返回到U层中都是把DataTable当做Model来使用,而我们的Model却被放置在了一边,于是我们的三层结构就被破坏了。现在我们的系统简单返回的是一张表,如果返回的是多张表,一个DataTable够吗?于是泛型应用而生。借用了一张图:


   


三、数组、集合、泛型


  


四、代码部分


以学生收取金额为例:


D层代码:


Public Class QueryGetCashDAL : Implements IDAL.QueryGetCashIDAL '实现接口
    Public Function QueryGetCashIDAL(GetCash As Entity.QueryGetCash) As List(Of Entity.QueryGetCash) Implements IDAL.QueryGetCashIDAL.QueryGetCashIDAL
        Dim SqlHelperObject As New SqlHelper.LoginSqlHelper
        Dim dt As DataTable  '定义接受DataTable的dt
        Dim Sql As String
        Dim myList As New List(Of Entity.QueryGetCash)  '定义接受DataTable转换后List

        '将实体层字段赋值给参数
        Dim SqlParams As SqlParameter() = {New SqlParameter("@StartDate", GetCash.StartDate), New SqlParameter("@EndDate", GetCash.EndDate)}

        '查询语句
        Sql = "select * from T_RechargeInfo where RechargeDate>=@StartDate and RechargeDate<=@EndDate"

        '传到SQLHelper层,返回内容给dt
        dt = SqlHelper.LoginSqlHelper.GetDataTable(Sql, CommandType.Text, SqlParams)

        '判断DataTable表中是否有数据
        If (dt.Rows.Count > 0) Then
            ' 将DataTable转换成泛型
            myList = ConvertHelper.ConvertHelper.ConvertToList(dt, myList)
            Return myList
        Else
            Throw New Exception("没有记录!")
            Return Nothing
        End If
    End Function
End Class

DataTable转List:


Module ConvertHelper
    Public Class ConvertHelper
        Public Shared Function ConvertToList(Of T As {New})(dt As DataTable, ts As IList(Of T))
            Dim type As Type = GetType(T) '获得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 '定义计数初始为0

                '遍历所有对象属性    
                While intCount < array.Length 'length表示所有维数中元素的总和    
                    Dim pr As PropertyInfo = array(intCount) 'pr表示元素中含有的属性,并提供对数据访问    
                    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 '每条记录中字段+1
                    Continue While
                End While
                '添加对象到泛型集合中    
                ts.Add(act)
            Next
            Return ts
        End Function
    End Class
End Module

U层中结合DataGridView控件使用:


Try
            '获得起始终止时间给实体
            GetCash.StartDate = StartDate.Text.Trim()
            GetCash.EndDate = EndDate.Text.Trim()

            QueryDate = FacadeObject.FacadeQueryGetCash(GetCash)

            '判断卡号是否存在
            If QueryDate.Count = 0 Then
                MessageBox.Show("卡号不存在", "温馨提示")
            Else
                DGQueryGetCash.Rows.Add(QueryDate.Count)    '数据表添加行,行数等于数据行数  
                For i = 0 To QueryDate.Count - 1
                    '变量写入行上的每个数据,rows代表行,Cell代表第几个格  
                    DGQueryGetCash.Rows(i).Cells(0).Value() = QueryDate(i).CardNo
                    DGQueryGetCash.Rows(i).Cells(1).Value() = QueryDate(i).RechargeCash
                    DGQueryGetCash.Rows(i).Cells(2).Value() = Format(QueryDate(i).RechargeDate)
                    DGQueryGetCash.Rows(i).Cells(3).Value() = QueryDate(i).RechargeTime
                    DGQueryGetCash.Rows(i).Cells(4).Value() = QueryDate(i).UserID
                    DGQueryGetCash.Rows(i).Cells(5).Value() = QueryDate(i).IsCheck
                Next
                MessageBox.Show("查询成功", "恭喜您")
            End If
        Catch ex As Exception
            MessageBox.Show(ex.Message.ToString())
        End Try


在U层、Facade层、B层以及接口处把返回类型和接收类型改成List


五、LIst优点


从上面例子中我们可以看到泛型的使用原则,它可以把实体中定义的属性对应字段存储起来,然后在U层中根据对应的字段在DataGridView控件中显示,这样既可以按需动态增加属性,也可以保证安全。


开始的时候对这部分很不理解,听到别人说泛型怎样觉得很高大上,其实路是一步步走过来的,只要踏实走好,问题自然迎刃而解。继续......

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 41
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 41
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值