Friday 29 March 2013

[DataMember] Hides Dead Code From ReSharper

18 months ago I wrote a post describing how unit tests obscure dead code. The solution I found was to unload all the test projects and see what ReSharper then threw up. I’ve since discovered another case where ReSharper will not warn you about unused members - the [DataMember] attribute.

If you’ve done any serialization in C# I’m sure you’ve come across the pair of attributes DataContract and DataMember. You annotate your classes [1] with them like so to allow them to be serialized (e.g. with WCF):-

[DataContract]
public class MyType
{
  [DataMember]
  public string MyValue { get; private set; }
}

Whilst doing the refactoring I mentioned in my last post one of the changes I was going to make was to remove the [DataMember] attribute from a property that did not need to be serialized because it was a cached value. A few seconds after removing the attribute, the name when dark grey and ReSharper pointed out it was not used. Somewhat bemused I undid my change and lo and behold ReSharper stopped pointing out it was redundant.

I can only imagine (or I could read the manual) that this behaviour is because ReSharper has to assume the property is accessed via reflection and so in some codebases it’s likely to report a false positive. To a degree we already have this problem with the classes we use with the Plossum command line parser because they are only poked by reflection, although I set a default value in the constructor in this case to placate ReSharper/FxCop.

For the moment, until I follow my own advice and RTFM, I’m just temporarily commenting out the [DataMember] attributes on all properties and waiting a few seconds to give ReSharper time to think. Then I put the attributes back again where R# thinks they are in use. Of course they may only be in use because of the unit tests, which is quite likely because I always write a unit test to verify that a class correctly supports serialization [2]. However I’m hopeful that those clever JetBrains developers will one day allow me to have my cake and eat it too.

 

[1] I’ve never been entirely comfortable with this approach to serialization as it feels wrong to be adding the responsibility for serialization to the class itself. In C++ your serialization code was often orthogonal to the class itself as you might read and write multiple formats. These two attributes don’t seem overly invasive but the XML serialization attributes certainly appear to be.

[2] All it does is create an instance of the class, serialize and deserialize with DataContractSerializer and then compare the properties against the values used to construct the original instance. Any derived properties are also verified to ensure that an internal OnDeserialized() method has been added where necessary.

No comments:

Post a Comment