Проверка необязательного поля при использовании пользовательской сериализации .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);
}
}
Другие советы
Я знаю, что это очень старая тема, но моим решением этой проблемы было создание метода расширения Информация о сериализации класс такой:
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;
}
}
}