TListClass(TList)

Imports System.ComponentModel
Imports System.Data.SqlClient
Imports System.Reflection

Public Class TData(Of T As New)
Implements IDisposable
Public Property DTable() As DataTable
Public Property DList() As List(Of T)
Public Sub New()
Me.DList = New List(Of T)
End Sub
''' <summary>
''' DataReaderまたはDataTableの内容をList(T)に展開する
''' </summary>
''' <param name="dr">展開対象のDataReader</param>
Public Sub SetTList(ByVal Optional dr As SqlDataReader = Nothing)
If dr IsNot Nothing Then
Me.ConvertToTClassByDataReadere(dr)
Return
End If
If DTable IsNot Nothing AndAlso DTable.Rows.Count > 0 Then
Me.ConvertToTClassByDataTable()
Return
End If
End Sub
''' <summary>
''' DataReaderの内容をList(T)に展開する
''' </summary>
''' <param name="dr"></param>
Protected Sub ConvertToTClassByDataReadere(ByVal dr As SqlDataReader)
Dim tBase As New T
DList = New List(Of T)
Dim properties As PropertyDescriptorCollection = TypeDescriptor.GetProperties(tBase.GetType)
While dr.Read
tBase = New T
For Each prop As PropertyDescriptor In properties
tBase.GetType.GetProperty(prop.Name).SetValue(tBase, If(dr(prop.Name) IsNot DBNull.Value, dr(prop.Name), Nothing))
Next
DList.Add(tBase)
End While
End Sub
''' <summary>
''' DataTableの内容をList(T)に展開する
''' </summary>
Protected Sub ConvertToTClassByDataTable()
Dim tBase As New T
DList = New List(Of T)
Dim properties As PropertyDescriptorCollection = TypeDescriptor.GetProperties(tBase.GetType)
For Each dRow In DTable.Rows
tBase = New T
For Each prop As PropertyDescriptor In properties
tBase.GetType.GetProperty(prop.Name).SetValue(tBase, If(dRow(prop.Name) IsNot DBNull.Value, dRow(prop.Name), Nothing))
Next
DList.Add(tBase)
Next
End Sub
''' <summary>
''' List(T)の件数を取得
''' </summary>
''' <returns></returns>
Public Function Count() As Long
If DList IsNot Nothing Then Return DList.Count
If DTable IsNot Nothing Then Return DTable.Rows.Count
Return 0
End Function
''' <summary>
''' List(T)に新要素を追加
''' </summary>
''' <param name="val">追加する要素</param>
Public Sub Add(ByVal val As T)
DList.Add(val)
End Sub
''' <summary>
''' List(T)の指定したIndexに要素を追加
''' </summary>
''' <param name="val">追加する要素</param>
''' <param name="index">追加位置</param>
Public Sub Insert(ByVal val As T, index As Long)
DList.Insert(index, val)
End Sub
''' <summary>
''' List(T)内の指定項目の値が指定値である要素を全て削除
''' </summary>
''' <param name="keyName">指定項目</param>
''' <param name="keyValue">指定地</param>
Public Sub RemoveByKey(ByVal keyName As String, keyValue As Object)
If DList Is Nothing Then Return
'---指定のpropertyが存在しない場合削除しない
If IsNothing(DList(SINGLE_RECORD).GetType.GetProperty(keyName)) Then Return
DList.RemoveAll(Function(x) x.GetType().GetProperty(keyName).GetValue(x) = keyValue)
End Sub
''' <summary>
''' 一致するデータをList(T)から削除
''' </summary>
''' <param name="item">削除対象データ</param>
''' <returns></returns>
Public Function Remove(ByVal item As T) As Boolean
Dim isMatch As Boolean
If DList.Count = NO_VALUE Then Return True
'---引数で指定されたItemとクラス内Listの各propertyの値を比較し、一致した場合削除
For i As Integer = DList.Count - 1 To 0 Step -1
Dim val As T = DList(i)
isMatch = True
For Each wrk As PropertyInfo In DList(SINGLE_RECORD).GetType().GetProperties()
If val.GetType().GetProperty(wrk.Name).GetValue(val) <> item.GetType().GetProperty(wrk.Name).GetValue(item) Then
isMatch = False
Exit For
End If
Next
If isMatch Then
DList.RemoveAt(i)
End If
Next
Return True
End Function

#Region "IDisposable Support"
Private disposedValue As Boolean ' 重複する呼び出しを検出するには

' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not disposedValue Then
If disposing Then
' TODO: マネージ状態を破棄します (マネージ オブジェクト)。
If Not IsNothing(Me.DTable) Then
Me.DTable.Clear()
Me.DTable = Nothing
End If
If Not IsNothing(Me.DList) Then
Me.DList.Clear()
Me.DList = Nothing
End If
End If
' TODO: アンマネージ リソース (アンマネージ オブジェクト) を解放し、下の Finalize() をオーバーライドします。
' TODO: 大きなフィールドを null に設定します。
End If
disposedValue = True
End Sub

' TODO: 上の Dispose(disposing As Boolean) にアンマネージド リソースを解放するコードが含まれる場合にのみ Finalize() をオーバーライドします。
'Protected Overrides Sub Finalize()
' ' このコードを変更しないでください。クリーンアップ コードを上の Dispose(disposing As Boolean) に記述します。
' Dispose(False)
' MyBase.Finalize()
'End Sub

' このコードは、破棄可能なパターンを正しく実装できるように Visual Basic によって追加されました。
Public Sub Dispose() Implements IDisposable.Dispose
' このコードを変更しないでください。クリーンアップ コードを上の Dispose(disposing As Boolean) に記述します。
Dispose(True)
' TODO: 上の Finalize() がオーバーライドされている場合は、次の行のコメントを解除してください。
' GC.SuppressFinalize(Me)
End Sub
#End Region
End Class