views:

113

answers:

2

I'm trying to determine why this type isn't serializable (as tested by Type.IsSerializable())

<Serializable()> _
Public MustInherit Class WellKnownInstanceCollectionWithTypedId(Of T As WellKnownInstanceWithTypedId(Of IdT), IdT)
    Inherits ReadOnlyCollection(Of T)

    Public Sub New(ByVal list As IList(Of T))
        MyBase.New(list)
    End Sub


    Public Function GetById(ByVal id As IdT) As T
        Return Me.FirstOrDefault(Function(item) item.Id.Equals(id))
    End Function

End Class

I know it has something to do with my GetById function, because if I remove that everything is fine. Can someone tell me what I need to change to have this type be serializable?

Update:

When I change my GetById implementation as such, everything is fine. Obviously this has something to do with Linq (as suggested below) - can anyone give me further details on why this is so?

    Public Function GetById(ByVal id As IdT) As T
        For Each i In Me
            If i.Id.Equals(i) Then
                Return i
            End If
        Next
        Return Nothing
    End Function
+2  A: 

Serializable types need to have a default constructor

James O'Sullivan
@James: ReadOnlyCollection does have one, so this isn't the issue.
DanP
@DanP But constructors are not inherited so this may still be an issue.
Mark Hurd
@James; well, in this case, it doesn't seem to matter. Removing the inital impl of my GetById method results in the class being serializable.
DanP
+3  A: 

It could be relate to the lambda expression (Function) in GetById.
Try converting it to an AddressOf call to see if the background closure VB.NET is creating for you is getting in the way of serialization.

(Promoting comment to answer)
In your complete code, to test whether it is LINQ or the closure, just change your original code to Return Me.FirstOrDefault(False).

I believe that will make it serialisable again. If so, you can use AddressOf id.Equals instead of Function(Item)... which is the same sematics unless you wanted to cater for a null (Nothing) id.

Mark Hurd
Very strange...when I replaced my GetById impl to use interation instead of linq it became serializable...I'd love to know further reasoning behind this, though.
DanP
I actually ended up externalizing my linq functions as specifications and had by GetById function call these instead (I had other cases where serialization was failing due to this); very strange, but I now have everything working as expected - thanks for the hints!
DanP