15

次のようなクラスがあるとします。

[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);
    }
}

addressを呼び出す前に、フィールドの値が存在するかどうかをテストするにはどうすればよいinfo.GetString(address)ですか?

はい、単純にヌルaddressフィールドを記述できることは理解していますが、実際の問題は、以前のバージョンのMyClassにはアドレス フィールドがなかったことです。

注:カスタム シリアライゼーションを使用するのには十分な理由があります。シングルトンとして使用されているいくつかの静的フィールドがあり、デフォルトの逆シリアル化はそれを尊重しません。

4

2 に答える 2

21

興味深いアプローチの1つは、GetEnumeratorforeach)を使用して名前と値のペアを反復処理し、名前switchにaを使用してそれぞれを順番に処理できることです。

ただし、実装は少し非標準のようです。ここの例から:

    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);
    }

しかし、あなたも使用できるようです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);
    }
}
于 2009-08-26T08:45:17.707 に答える