views:

180

answers:

4

I came across this code while working through code-analysis warnings on our code base. I want to change the name, but not if it will cause a serialization issue. While it looks to me like there is no point in it being serializable, I just wanted to check to make sure I'm not missing something before I strip the attribute.

[Serializable]
public class FileIsNotReadonlyVerifier : IFileVerifier
{
    #region IFileVerifier Members
    public void Verify(FileInfo file, FlatFileTrafficSystem system)
    {
        if ((file.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
        {
            throw new VerificationException(Resources.VerificationException_FileIsReadonly);
        }
    }
    #endregion
}
A: 

Iff the class carries no state at all (as in your example), I would agree, that it is pointless, UNLESS you need it for some obscure remoting scenario (and some other probably equally weird scenarios).

leppie
+4  A: 

Not entirely. I once worked with an XML standard (Open Travel Alliance) that had a type that was just an emtpy tag with no properties <Success />. So this was just implemented as a serializable class in my code with no properties. It was used in response messages from a web service to indicate that the server process was successful.

Keith
(XmlSerializer doesn't care about `[Serializable]`)
Marc Gravell
+7  A: 

Yes please mark this as serializable.The reason being that if you don't anyone who uses your type will be unable to serialize an instance of this class.

[Serializable] 
public class MyType {

  // Breaks serialization.  
  private readonly FileIsNotReadonlyVerifier _verifier;

  // Might work, might break.  Depends on the implementation.  Have to use 
  // another context variable to serialize / deserialize this. 
  private readonly IFileVerifier _otherVerifier;

}

The only way to make it work in this case is to make the variable non-serializable, use another variable to track the state, and override the special serialization methods with fixup logic.

I've run into this problem several times and it's extremely frustrating. Most notably I've run into it in places where people were creating custom string comparers which had no members. In order to serialize my types I had to jump through a lot of hoops. Very frustrating.

JaredPar
Why lots of hoops? Surely you could just wrap it, given a specific interface.
leppie
@leppie, yes. But it requires either 1) another variable and hacky fixup logic or 2) a wrapper class which serves as a serialization container and proxies the call to the real interface. Either case is much more work than the default of doing nothing.
JaredPar
In that case, you'd just add [NonSerialized] above _verifier and do it in the callback.
Marc Gravell
@Marc, yes that works fine for the case where I have the concrete type. But when I have only the interface and multiple possible implementations it requires [NonSerialized] plus other context variables to rebuild the verifier.
JaredPar
IMO... why are you serializing something that you aren't in complete control of? That sounds like a recipe for data that you can't read again...
Marc Gravell
@Marc, how am I not in control here? In this case I understand the N implementations of the interfaces and which ones are or are not serializable. I'm merely stating that having any of the types be non-serializable forces an additional context variable in order to properly recreate the implementation at a later time.
JaredPar
+5  A: 

Your class isn't sealed; if the intention is that somebody could subclass it and need to serialize it, then perhaps add [Serializable].

However; I wouldn't add [Serializable] "just because"; serialization (like threading or inheritance) is something that should be planned, designed and tested. If you don't currently serialize the type or foresee a need to serialize it, then the chances are that you haven't designed/tested it adequately for those scenarios (which is 100% correct; you don't waste time writing unnecessary code).

If somebody else uses your class and wants to be serializable, they can do that by marking their local field as [NonSerialized] and handling it manually (perhaps in the callbacks).

Note also that in many ways BinaryFormatter (which is the main consumer of [Serializable]) itself has design issues and is fairly brittle. There are contract-based serializers that offer far more stability.

Marc Gravell
For contract-based serializers, are you referring to the structure implemented in WCF or something else? If WCF, is the serialization contract built to be portable beyond the use of WCF into other contexts?
Aethyrial
Either or ;-p WCF data-contracts are portable via WSDL; but other contract-based serializers exist; for example "protocol buffers" is a binary serialization format (with .NET versions protobuf-net (mine ;-p) and dotnet-protobufs) - and that is very portable, but you need to do the transport yourself; http://code.google.com/p/protobuf/wiki/ThirdPartyAddOns
Marc Gravell