2008-10-06 3 views
3

Пожалуйста, обратите внимание этот пример класса:Перекрытие сериализации для конкретного типа .NET

[Serializable] 
public class SomeClass 
{ 
    private DateTime _SomeDateTime; 

    public DateTime SomeDateTime 
    { 
     get { return _SomeDateTime; } 
     set { _SomeDateTime = value; } 
    } 
} 

Я хотел бы изменить сериализации любого DateTime объявлен в классе по моим собственным правилам. Члены этого класса будут часто меняться, и я не хочу поддерживать собственный сериализатор для каждого изменения. Также я хотел бы, чтобы это поведение было унаследовано подклассами, а не кодировать собственный сериализатор для каждого. Сериализация выводится веб-службой. Спасибо за любую помощь!

ответ

3

Посмотрите на атрибуты OnSerializing и OnDeserializing, чтобы вызвать пользовательские методы, когда ваши объекты сериализованы. вы можете создать там некорректную логику и отделить процесс сериализации от фактических типов данных.

+0

Как это сделать, если эти делегаты не делают доступным объект SerializationInfo? – skolima 2009-03-11 14:44:20

3

Вы думали о том, просто используя Nullable времени даты

public DateTime? SomeDateTime {get; set;} 

Таким образом, вы можете иметь нулевое значение в качестве законного значения в вашем классе. Как правило, вы хотите избежать выборочной сериализации, когда это возможно. Как только вы выполните обычную сериализацию, такую ​​как реализация ISerializable, вы застряли в ней, и все другие производные классы застряли с ней.

Помните, какая боль в прикладе должна всегда перекрывать члены ISerializable для пользовательских исключений? Это связано с тем, что System.Exception реализует ISerializable, и поэтому все производные исключения (что означает все) должны реализовывать эти члены, если вы когда-либо ожидаете, что они перейдут через AppDomains.

+0

Я использую это через веб-службу, поэтому он автоматически преобразует DateTime? to DateTime.MinValue. Я исправлю вопрос. – 2008-10-06 11:58:00

0

Ну, вы можете использовать метод bool ShouldSerializeSomeDateTime() для включения/отключения сериализации отдельных членов, но я не думаю, что это совсем то, что вам нужно. Другим распространенным вариантом является добавление члена, который делает сам формат:

public string SomeDateTimeFormatted { get {return theField == DateTime.MinValue? "": TheField.ToString ("R");} // или любой другой формат множество {... напротив ...}}

Это лучше придерживаться встроенной сериализации, если вы можете, хотя - частично, чтобы уменьшить количество кода, который вам нужно написать. Предположение Джоша о нулевом DateTime (DateTime?) Является хорошим, хотя это может быть и не совсем пустая строка с форматированной строкой - я ожидаю, что она будет использовать разметку xsi: nil.

Смежные вопросы