#c# #serialization
#c# #сериализация
Вопрос:
Я создаю класс DataContract, который будет использоваться при десериализации из строки. Я прочитал какую-то статью и узнал, что я могу написать ондесериализованный метод, который будет вызван после десериализации, прежде чем вернуть объект. Вот как это выглядит в моем классе.
Это работает нормально, если какой-либо элемент ОТСУТСТВУЕТ в потоке. Как бы то ни было, мой вопрос в том, что в случае, если элемент ОТСУТСТВУЕТ в потоке, кто может гарантировать, что эти неинициализированные значения равны 0, DateTime.MinValue и null соответственно?
Кроме того, если член int имеет значение 0, как я узнаю, что он из потока или не инициализирован?
[DataContract]
public class MyData
{
[DataMember]
public int MemberA { get; set; }
[DataMember]
public DateTime MemberB { get; set; }
[DataMember]
public string MemberC { get; set; }
[OnDeserialized]
void OnDeserialized(StreamingContext c)
{
if (MemberA == 0)
MemberA = 100;
if (MemberB == DateTime.MinValue)
MemberB = DateTime.Now;
if (MemberC == null)
MemberC = "MemberC";
}
}
Я ищу лучший подход, что-то вроде
if (NotInitialized(MemberA))
MemberA = xxx;
Ответ №1:
Вы могли бы рассмотреть возможность использования нулевого типа, который будет автоматически установлен null
, если данные отсутствуют во время десериализации:
[DataMember]
public int? MemberA { get; set; }
[DataMember]
public DateTime? MemberB { get; set; }
[DataMember]
public string? MemberC { get; set; }
Обратите внимание на добавление ?
к каждому типу значения, которое указывает, что оно также может быть null
.
Легко определить, имеют ли они значения:
if (MemberA.HasValue)
{
// Value = MemberA.Value;
... do something
}
Вы также можете убедиться, что элемент не выводится, если вы снова сериализуете класс, используя атрибуты на DataMember
:
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int? MemberA { get; set; }
Это означает, что MemberA
оно будет полностью исключено из ваших сериализованных результатов, если оно имеет null
значение.
Комментарии:
1. Итак, в случае отсутствия значения из потока, этот тип с нулевым значением будет гарантированно равен null? Можете ли вы показать мне ссылку?
2. Итак, если
MemberA.HasValue
значение равно false, то значение равноnull
. Это работает и дляint
s, поэтому его не будет0
в случае отсутствия в вашем потоке данных.3. IsRequired = false означает, что если это значение равно нулю, то не сериализуйте? если EmitDefaultValue = true, как установить значение по умолчанию?
4. Итак, если
EmitDefaultValue = true
тогда [значение] по умолчанию для элемента должно быть сгенерировано в потоке сериализации . Так что дляint
этого будет0
, и так далее. Значение равно значению по умолчанию для этого типа значения.