ShouldSerialize* functions should refer to an existing property

The .NET framework’s XmlSerializer class allows to control the conditional serialization of individual properties based on a specific (but not well-documented) convention: When deciding whether to serialize a property, the serializer will check if a no-args function with a boolean return value and the name ShouldSerialize{PropertyName} exists. If it does exist, then the return value of that function determines whether the property will be serialized. If it does not exist, the property will be serialized by default (unless other annotations on the property prevent this).

This is of course pretty fragile. If you decide to refactor your code at a later point and change the name of a property from Foo to Bar, you also need to change the name of the function to ShouldSerializeBar. It’s also easy to get a typo into the function name for more complex property names. In either case will the functionality silently break.

A possible Sonar rule could raise an issue if a class contains a function that

  1. is public
  2. is parameterless
  3. has a boolean return value
  4. has a name that starts with ShouldSerialize (case-sensitive)
  5. does not end with the name of any of the public properties or fields in that class.

While there is of course the possibility of identifying false-positives, it seems a bit unlikely that you would have a function with these very specific requirements without intending to use this pattern.

Non-complian code:

Public Class A

    Public Property Foo As Integer
    Public Property Bar As New List(Of B)
    
    Public Function ShouldSerializefoo() As Boolean ' NONCOMPLIANT - case mismatch
        Return Foo <> 0
    End Function

    Public Function ShouldSerializeBaz() As Boolean ' NONCOMPLIANT - typo/unknown property
        Return Bar IsNot Nothing AndAlso Bar.Count() > 0
    End Function

End Class

Compliant code:

Public Class A

    Public Property Foo As Integer
    Public Property Bar As New List(Of B)

    Public Function ShouldSerializeFoo() As Boolean ' COMPLIANT
        Return Foo <> 0
    End Function
    
    Public Function ShouldSerializeBar() As Boolean ' COMPLIANT
        Return Bar IsNot Nothing AndAlso Bar.Count() > 0
    End Function

End Class

External references:

This ShouldSerialize{PropertyName} convention is not only used by the XmlSerializer, but also with Windows Forms controls (and is probably where it originated before the serializer adopted it):

The convention has also been adapted by other serialization frameworks, such as json.net and protobuf.net:

(I couldn’t find any official documentation regarding the behaviour in the XmlSerializer. It’s a semi-hidden feature. It’s been around for a while and “just works” this way.)

While there are other naming-convention based functions, like {PropertyName}Specified and Reset{PropertyName}, those don’t seem as universally used and more prone to false-positives.

Type:

  • Code Smell

thanks @CrushaKRool , this looks like a good rule!