使用.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
的,没有一个地址字段。
注意:我对使用自定义序列化很好的理由。但是也有一些被用作单身和默认反序列化将不尊重一些静态字段。
解决方案
那么,一个有趣的方法是,你可以使用的 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