Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Linq.Expressions

'Public NotInheritable Class CPersona
'  Private _nombre As String
'  Private _fechaNac As String

'  Public Property Nombre() As String
'    Get
'      Return _nombre
'    End Get
'    Set(ByVal value As String)
'      _nombre = value
'    End Set
'  End Property

'  Public Property FechaNac() As DateTime
'    Get
'      Return _fechaNac
'    End Get
'    Set(ByVal value As DateTime)
'      _fechaNac = value
'    End Set
'  End Property
'End Class

Public NotInheritable Class CPersona
  Public Property Nombre() As String
  Public Property FechaNac() As DateTime
End Class

Module Test

  Sub Main()

    Dim listPersona = New List(Of CPersona)()
    listPersona.AddRange(New CPersona() { _
      New CPersona With { _
        .Nombre = "Elena", .FechaNac = New DateTime(1990, 6, 25)}, _
      New CPersona With { _
        .Nombre = "Manuel", .FechaNac = New DateTime(1991, 9, 21)}, _
      New CPersona With { _
        .Nombre = "Rocío", .FechaNac = New DateTime(1991, 3, 15)} _
     })

    'Dim listPersona = New List(Of CPersona) From { _
    '  New CPersona With { _
    '    .Nombre = "Elena", .FechaNac = New DateTime(1990, 6, 25)}, _
    '  New CPersona With { _
    '    .Nombre = "Manuel", .FechaNac = New DateTime(1991, 7, 26)} _
    ' } '  a partir de VB 10

    Dim personas1991 As String = ""

    'Dim exprNacidoEnAño As Expression(Of Func(Of CPersona, Boolean)) = _
    '  Function(p) p.FechaNac.Year = 1991

    ' Function(p) p.FechaNac.Year = 1991
    'Dim parametro_p As ParameterExpression = _
    '  Expression.Parameter(GetType(CPersona), "p")
    'Dim m1 As MemberExpression = _
    '  Expression.Property(parametro_p, "FechaNac")
    'Dim left As MemberExpression = Expression.Property(m1, "Year")
    'Dim right As ConstantExpression = _
    '  Expression.Constant(1991, GetType(Integer))
    'Dim exprb As BinaryExpression = Expression.Equal(left, right)
    'Dim exprNacidoEnAño As Expression(Of Func(Of CPersona, Boolean)) = _
    '      Expression.Lambda(Of Func(Of CPersona, Boolean))( _
    '        exprb, _
    '        New ParameterExpression() {parametro_p})

    'For Each p In listPersona
    '  Dim esNacidoEn As Boolean = exprNacidoEnAño.Compile().Invoke(p)
    '  If esNacidoEn Then
    '    personas1991 += p.Nombre + Environment.NewLine
    '  End If
    'Next

    Dim añoNac As Integer = 1991
    ' Function(p, año) p.FechaNac.Year = año
    Dim parametro_p As ParameterExpression = _
      Expression.Parameter(GetType(CPersona), "p")
    Dim m1 As MemberExpression = _
      Expression.Property(parametro_p, "FechaNac")
    Dim left As MemberExpression = Expression.Property(m1, "Year")
    Dim right As ParameterExpression = _
      Expression.Parameter(GetType(Integer), "año")
    ' right = parámetro año
    Dim exprb As BinaryExpression = Expression.Equal(left, right)
    Dim exprNacidoEnAño As Expression(Of  _
         Func(Of CPersona, Integer, Boolean)) = _
           Expression.Lambda(Of Func(Of CPersona, Integer, Boolean))( _
                exprb, _
                New ParameterExpression() {parametro_p, right})

    For Each p In listPersona
      If exprNacidoEnAño.Compile().Invoke(p, añoNac) Then
        personas1991 += p.Nombre + Environment.NewLine
      End If
    Next

    Console.WriteLine(personas1991)
  End Sub
End Module
