オプションのフィールドのためのテスト.NETカスタム・シリアライズを使用して
-
20-09-2019 - |
質問
このようなクラスが与えられます:
[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;
}
}
}
所属していません StackOverflow