Question

Given a class like this one:

[Serializable]
public class MyClass {
    string name;
    string address;

    public MyClass(SerializationInfo info, StreamingContext context){
        name = info.GetString("name");
        if(/* todo: check if a value for address exists */)
            address = info.GetString("address");
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context){
        info.AddValue(name);
        if(address != null)
            info.AddValue(address);
    }
}

How do I test whether a value for the address field exists before calling info.GetString(address)?

Yes, I do understand that I could simply write a null address field but my real problem is that earlier versions of MyClass, did not have an address field.

Note: I have good reasons for using custom serialization. There are some static fields that are being used as singletons and the default deserialization will not respect that.

Was it helpful?

Solution

Well, one intriguing approach is that you could use GetEnumerator (foreach) to iterate over the name/value pairs, using a switch on the name to handle each in turn?

The implementation seems a bit non-standard, though; from the example here:

    SerializationInfoEnumerator e = info.GetEnumerator();
    Console.WriteLine("Values in the SerializationInfo:");
    while (e.MoveNext())
    {
        Console.WriteLine("Name={0}, ObjectType={1}, Value={2}",
             e.Name, e.ObjectType, e.Value);
    }

But it looks like you can also use SerializationEntry:

[Serializable]
class MyData : ISerializable
{
    public string Name { get; set; }
    public int Value { get; set; }

    public MyData() { }
    public MyData(SerializationInfo info, StreamingContext context)
    {
        foreach (SerializationEntry entry in info)
        {
            switch (entry.Name)
            {
                case "Name":
                    Name = (string)entry.Value; break;
                case "Value":
                    Value = (int)entry.Value; break;
            }
        }
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Name", Name);
        info.AddValue("Value", Value);
    }
}

OTHER TIPS

I know this is a very old thread, but my solution to this issue was to create an extension method of the SerializationInfo class like this:

namespace System.Runtime.Serialization
{
  public static class SerializationInfoExtensions
  {
    public static bool Exists(this SerializationInfo info, string name)
    {
      foreach (SerializationEntry entry in info)
        if (name == entry.Name)
          return true;
      return false;
    }
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top