Mark field as not serialized with [NonSerialized()]

News to me...

If you're serializing an object and there are fields on it which you do not want to serialize, you can stop the formatter (BinaryFormatter/SoapFormatter) from writing it to the stream with careful use of the NonSerialized attribute.  To illustrate:

class Foo
{
    private int _bar;
    private string _filename;
    [NonSerialized()] private Stream _myFile;
}

Of course, if you deserialize the object, the field which you may have had beforehand will be null.  The solution here is either to lazy initialize the field, e.g.

public Stream MyFile
{
    get
    {
        if(_myFile == null)
            _myFile = OpenMyFile();
        return _myFile;
    }
}

...or the potentially more elegent method of using IDeserializationCallback.  This will tell you when an object has been deserialized, so you can setup internal state before the object is returned to the caller.  For example:

class Foo : IDeserializationCallback
{
    private int _bar;
    private string _filename;
    [NonSerialized()] private Stream _myFile;

    void IDeserializationCallback.OnDeserialization(object sender)
    {
        // open it...
        _myFile = OpenMyFile();
    }
}

This solution lets you do error handling at the point of instantiation, rather than the point of use.  In the lazy-loading example, a FileNotFound (for example) would only be thrown the first time you used it.  This may not match your specification re the use of the object.  IDeserializationCallback lets you throw exceptions at the point of creation.  It depends on your class and situation which is better for you, but we do have two options available to us, which is great!

No Comments