0

I have the following setup:

[Serializable]
public class TickerSymbol : ISerializable
{
    public readonly string Symbol;

    public TickerSymbol(string Symbol)
    {
        this.Symbol = Symbol;
    }

    protected TickerSymbol(SerializationInfo info, StreamingContext context)
    {
        // Call Order: 3
        Symbol = info.GetString("Symbol");
    }

    public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue<string>("Symbol", Symbol);
    }

    [OnDeserialized]
    public void OnDeserialized(StreamingContext context)
    {
        // Call Order: 1
        // Do something that requires the symbol to not be null
    }
}

[Serializable]
public class EquitySymbol : TickerSymbol, ISerializable
{
    public EquitySymbol(stirng Symbol)
        : base(Symbol)
    {
    }

    protected EquitySymbol(SerializationInfo info, StreamingContext context)
        : base(info, context)
    {
        // Call Order: 4
    }

    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        base.GetObjectData(info, context);
    }

    [OnDeserialized]
    public void OnDeserialized(StreamingContext context)
    {
        // Call order 2
    }
}

I would have expected the methods marked with [OnDeserialized] to be called after the respective serialization constructors, but it appears as though they are called BEFORE their serialization constructors - how is this supposed to work??

William

William
  • 3,335
  • 9
  • 42
  • 74
  • The only way I can think of to call an instance method without actually constructing the instance first is with open delegates on a null object. To test If that's the case, try doing a check for `this == null` within the `OnDeserialized` method. – Chris Sinclair Jul 05 '12 at 23:59
  • Just did a test with your code and the order is correct - TickerSymbol's constructor, EquitySymbol's constructor, TickerSymbol's OnDeserialized, EquitySymbol's OnDeserialized. Which .NET version are you using? Please show how do you serialize/deserialize the object. – Ventsyslav Raikov Jul 06 '12 at 09:34
  • .NET 4.0 - so the correct order is for the OnDeserialized method to be called after the serialization constructor? – William Jul 06 '12 at 11:06
  • yep, that's how it works on my machine – Ventsyslav Raikov Jul 06 '12 at 11:12

1 Answers1

1

A possible solution might be to make Symbol a property rather than a field. Then, it would be possible to perform the required actions in the Symbol's setter, for example:

private string _symbol;

public string Symbol {
    get { return _symbol; }
    set { 
        _symbol = value;
        if (_symbol != null ) {
            // here the _symbol is right after deserialization,
            // and it is certainly not null
        }
    }
}

Also, it is generally not recommended to expose public fields in .NET because the fields are mostly considered to be an implementation detail, rather than an interface construct; see the following resources for more information:

Why won't anyone accept public fields in C#? - Great discussion on StackOverflow

CA1051: Do not declare visible instance fields http://msdn.microsoft.com/en-us/library/ms182141.aspx - Microsoft's explanation of the issue

Community
  • 1
  • 1
Andrew Sklyarevsky
  • 2,095
  • 14
  • 17