Search code examples
vb.netfilehelpers

How to cast object of type 'especific' to type 'FileHelpers.Events.INotifyRead in Multirecording


I'm trying to centralize all formatting and conversion rule in a single class especific. Using the interface INotifyRead(Of T As Class). When I implement the methods BeforeRead/AfterRead throws an exception: Unable to cast object of type 'Especific' to type 'FileHelpers.Events.INotifyRead`1[System.Object]'.

Below my code.

Using engine As New MultiRecordEngine(New RecordTypeSelector(AddressOf CifraRecordTypeSelector),
                                                GetType(RemessaRegistroCliente),
                                                GetType(RemessaRegistroContrato))
    Dim records = engine.ReadFile(_camArquivo)
End Using

Public NotInheritable Class RemessaRegistroCliente
    Implements INotifyRead(Of RemessaRegistroCliente)

    Public Sub AfterRead(e As AfterReadEventArgs(Of RemessaRegistroCliente)) Implements INotifyRead(Of RemessaRegistroCliente).AfterRead

    End Sub

    Public Sub BeforeRead(e As BeforeReadEventArgs(Of RemessaRegistroCliente)) Implements INotifyRead(Of RemessaRegistroCliente).BeforeRead

    End Sub
End Class

Public NotInheritable Class RemessaRegistroContrato
    Implements INotifyRead(Of RemessaRegistroContrato)

    Public Sub AfterRead(e As AfterReadEventArgs(Of RemessaRegistroContrato)) Implements INotifyRead(Of RemessaRegistroContrato).AfterRead

    End Sub

    Public Sub BeforeRead(e As BeforeReadEventArgs(Of RemessaRegistroContrato)) Implements INotifyRead(Of RemessaRegistroContrato).BeforeRead

    End Sub
End Class

Solution

  • Since MultiRecordEngine has no generic version, you cannot implement the generic INotifyRead(Of T) to handle events. Instead, assign delegates to the engine.

    Sub Main()
        Using engine As New MultiRecordEngine(New RecordTypeSelector(AddressOf CifraRecordTypeSelector),
                                                    GetType(RemessaRegistroCliente),
                                                    GetType(RemessaRegistroContrato))
            AddHandler engine.BeforeReadRecord, AddressOf BeforeReadRecordHandler
        End Using
    End Sub
    
    Private Sub BeforeReadRecordHandler(ByVal engine As EngineBase, ByVal e As BeforeReadEventArgs(Of Object))
    
    End Sub
    

    You'll also need to modify your classes to remove the generic interfaces:

    Public NotInheritable Class RemessaRegistroCliente
       'your fields
    End Class
    
    Public NotInheritable Class RemessaRegistroContrato
       'your fields
    End Class