Gracias Chris Haas por las palabras clave, pude investigar el tema más a fondo. Encontré another answer que no usa Of T As New
, que finalmente uso porque mis DTO no declaran ningún constructor.
Para el registro, esto es lo que finalmente se utilizo:
Private Function DataRowToObject(Of T)(ByVal source As DataRow) As T
Dim destination = GetType(T).GetConstructor(System.Type.EmptyTypes).Invoke({})
Dim props = destination.GetType.GetProperties()
Dim propnames = props.Select(Function(x) x.Name.ToLower)
For Each col In source.Table.Columns
Dim colname = col.ColumnName.ToLower()
If propnames.Contains(colname) Then
Dim prop = props.Where(Function(x) x.Name.ToLower = colname).First
If IsDBNull(source(col)) And prop.PropertyType Is GetType(String) Then
prop.SetValue(destination, "", Nothing)
ElseIf IsDBNull(source(col)) Then
prop.SetValue(destination, Nothing, Nothing)
Else
prop.SetValue(destination, source(col), Nothing)
End If
End If
Next
Return destination
End Function
Protected Function DataTableToList(Of T)(ByVal source As DataTable) As IList(Of T)
Dim destination As New List(Of T)
For Each row In source.Rows
Dim obj = DataRowToObject(Of T)(row)
destination.Add(obj)
Next
Return destination
End Function
Aquí es un cliente que utilice la función anterior:
Public Function PeopleAll() As IList(Of DTO.People)
Dim ResultTbl As New DataTable
adp.TableLoad("select * from people", ResultTbl)
Dim result = DataTableToList(Of DTO.People)(ResultTbl)
Return result
End Function
He aquí una muestra de mi objeto de transferencia de datos:
Public Class People
Public Overridable Property ID As Int64
Public Overridable Property Name As String
Public Overridable Property Email As String
End Class