オプションのフィールドのためのテスト.NETカスタム・シリアライズを使用して

StackOverflow https://stackoverflow.com/questions/1333201

質問

このようなクラスが与えられます:

[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の以前のバージョンでは、アドレスフィールドを持っていなかったということであることを理解してます。

注:私は、カスタムのシリアル化を使用するための十分な理由を持っています。シングルトンとして使用されていると、デフォルトの直列化復元はそれを尊重しないであろういくつかの静的なフィールドがあります。

役に立ちましたか?

解決

さて、1つの興味深いアプローチは、使用することができることである<のhref = "http://msdn.microsoft.com/en-us/library/system.runtime.serialization.serializationinfo.getenumerator.aspx" のrel = "noreferrer 「> GetEnumerator の(foreach)順番に各を処理するには、名前をswitchを使用して、名前/値のペアを反復するには?

の実装はいえ、少し非標準のようです。例からここをます:

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

他のヒント

私は、これは非常に古いスレッドです知っているが、この問題に対する私の解決策は、の拡張メソッドを作成することだったの SerializationInfoにのこのようなクラスます:

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;
    }
  }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top