Results 1 to 22 of 22

Thread: [.NET 2.0] Is Type/Structure Serializable

Threaded View

  1. #1

    Thread Starter
    PowerPoster formlesstree4's Avatar
    Join Date
    Jun 2008
    Posts
    3,250

    [.NET 2.0] Is Type/Structure Serializable

    I had a recent need for checking if a structure, and all the members inside of it, were serializable to avoid throwing a serialization exception on certain systems -where throwing one would be very costly, and in a situation where I might not know exactly what's being passed through the stream and attempting to be serialized.

    So after loads of google searching, I only found various ideas on how to do such a thing, mostly checking the single instance or the main structure itself. I can mark that as serializable, but what if one of the types inside isn't? Say, for some reason, the structure contains a TcpClient, or a MemoryStream. Neither of those is technically serializable and would throw an exception when attempting to be serialized.

    Finally, after a bit of experimenting in Visual Studio and with plenty of help from IntelliSense, I found a way to finally do it!

    Code:
        ''' <summary>
        ''' Determines if a structure is serializable.
        ''' </summary>
        ''' <typeparam name="T">The structure to test.</typeparam>
        ''' <returns>A boolean indicating if the structure can be serialized.</returns>
        ''' <remarks>It's really simple to check. If your structure is Foo, then you simply call the function as so:
        ''' IsStructureSerializable(Of Foo), and you will get a boolean value.</remarks>
        Public Function IsStructureSerializable(Of T As Structure)() As Boolean
    
            'Just a wrapper around the IsTypeSerializable.
            Return IsTypeSerializable(GetType(T))
    
        End Function
    
        ''' <summary>
        ''' Determines if a class is serializable.
        ''' </summary>
        ''' <typeparam name="T">The class to test.</typeparam>
        ''' <returns>A boolean indicating if the class can be serialized.</returns>
        ''' <remarks>It's pretty simple to check. If your class is called Foo, then you simply call the function as so:
        ''' IsClassSerializable(Of Foo), and you will get a boolean value.</remarks>
        Public Function IsClassSerializable(Of T As Class)() As Boolean
    
            'Just a wrapper around the IsTypeSerializable.
            Return IsTypeSerializable(GetType(T))
    
        End Function
    
        ''' <summary>
        ''' Loops through the entire object to see if it is indeed serializable.
        ''' </summary>
        ''' <param name="type">The object Type to check.</param>
        ''' <returns>A boolean that indicates if the object passed is able to be successfully serialized.</returns>
        ''' <remarks>This function is recursive and will ignore any fields marked as "NonSerialized". 
        ''' However, if at any time there is a field that cannot be serialized, and it is not marked as "NonSerialized", the routine will end and immediately return false.</remarks>
        Public Function IsTypeSerializable(ByVal type As [Type]) As Boolean
    
            'Final serializable result
            Dim _result As Boolean = True
    
            'Make sure our current type is serializable
            If type.IsSerializable Then
    
                'Ok, so now get any sub-fields.
                Dim _subFields() As Reflection.FieldInfo = type.GetFields(Reflection.BindingFlags.Instance Or
                                                                          Reflection.BindingFlags.DeclaredOnly Or
                                                                          Reflection.BindingFlags.Public Or
                                                                          Reflection.BindingFlags.NonPublic)
    
                'Loop each subfield
                For Each _field As Reflection.FieldInfo In _subFields
    
                    'Get the type
                    Dim _type As Type = _field.FieldType
    
                    'See some details about this.
                    Console.WriteLine("-------------------------------")
                    Console.WriteLine(String.Format("Checking Type: {0}", _type.ToString()))
                    Console.WriteLine("Name: {0}", _field.Name)
                    Console.WriteLine("Private: {0}", _field.IsPrivate)
                    Console.WriteLine("Public: {0}", _field.IsPublic)
                    Console.WriteLine("Static: {0}", _field.IsStatic)
                    Console.WriteLine("Primitive: {0}", _type.IsPrimitive)
    
    
                    'Get an object array to see if this type is marked as NonSerialized.
                    Dim _attribues() As Object = _field.GetCustomAttributes(GetType(NonSerializedAttribute), False)
    
                    'Check
                    If _attribues IsNot Nothing AndAlso _attribues.Length > 0 Then
    
                        'This is to be ignored!
                        Console.WriteLine("Type {0} is marked for NonSerializable!", _field.ToString)
    
                    Else
    
                        'Check if it's a primitive
                        If _type.IsPrimitive Then
    
                            'It is.
                            _result = True
    
                        Else
    
                            'We have to go deeper.
                            _result = IsTypeSerializable(_type)
    
                        End If
    
                    End If
    
                    'Write out the result
                    Console.WriteLine("Type {0} {1} serializable", _type.ToString(), If(_result AndAlso _attribues.Length.Equals(0), "is", "is not"))
                    Console.WriteLine("-------------------------------")
                    Console.WriteLine()
    
                    'Check
                    If Not _result Then Exit For
    
                Next
    
            Else
    
                'The structure is not serializable
                _result = False
    
            End If
    
            'Give back the result
            Return _result
    
        End Function
    It takes the "Type" of the structure, so, you would pass it like so:
    Code:
    Public Structure XYZ
    End Structure
    
    Console.WriteLine(IsStructureSerializable(Of XYZ))
    Console.WriteLine(IsTypeSerializable(GetType(XYZ))
    The code will retrieve Private, Public, Static or Protected variables in a class or structure and, as far as I know, should always work. If there are any problems, please let me know!

    EDIT: Updated with a suggestion from Nick (who was gracious enough to provide an example on how to do it! Thanks Nick!)
    EDIT 2: Another update with overloads (suggested by Nick awhile back...I just got lazy).
    Last edited by formlesstree4; Jul 8th, 2011 at 11:02 AM. Reason: Updated code and included two additional routines.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width