C# 使用.NET自定义序列化时测试可选字段
对于这样一个类:C# 使用.NET自定义序列化时测试可选字段,c#,.net,serialization,binary-serialization,C#,.net,Serialization,Binary Serialization,对于这样一个类: [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
[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);
}
}
在调用info.GetString(address)
之前,如何测试address
字段的值是否存在
是的,我知道我可以简单地编写一个空的地址
字段,但我真正的问题是MyClass
的早期版本没有地址字段
注意:我有充分的理由使用自定义序列化。有一些静态字段被用作单例,默认的反序列化将不考虑这一点。好吧,一个有趣的方法是,您可以使用(
foreach
)在名称/值对上迭代,使用名称上的开关来依次处理每个
不过,实现似乎有点不标准;从示例中可以看出:
但看起来您也可以使用序列化条目
:
[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;
}
}
}
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;
}
}
}