Страница: 1 |
Вопрос: Десериализация и DefaultValueAttribute | Добавлено: 11.04.06 16:31 |
Автор вопроса: ![]() |
Допустим, имею класс с двумя свойствами:
<DefaultValueAttribute(5)> _
Public Property IntProp() As Integer Get IntProp = c_IntProp End Get Set(ByVal value As Integer) c_IntProp = value End Set End Property <DefaultValueAttribute("Вася")> _ Public Property StrProp() As String Get StrProp = c_StrProp End Get Set(ByVal value As String) c_StrProp = value End Set End Property Как видите, у каждого из свойств установлено дефолтное значение. Поэтому, когда я сериализую (через XmlSerializer и FileStream) экземпляр этого класса, то в итоговый XML-файл попадают только те свойства, значения которых отличаются от дефолтных. Например, если IntProp = 123 (не равно 5), а StrProp = "Вася" (совпадает с дефолтом), то XML будет выглядеть так: <?xml version="1.0"?>
<TestClass xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <IntProp>123</IntProp> </TestClass> т.е. StrProp в него не попадает. Что ж, так и задумано. Однако, когда я выполняю десериализацию из этого XML-файла, то StrProp получит пустое значение, - если только в конструкторе класса нет явной инициализации свойства StrProp в строку "Вася". Получается, что дефолтные значения нужно указывать в ДВУХ местах: в атрибутах DefaultValueAttribute и в коде конструктора. С одной стороны, это логично: атрибуты - это метаданные, а конструктор - это код. Но с другой стороны, очень хоцца сказать конструктору: "А ну-ка возьми-ка начальные значения всех членов класса из метаданных! чтоб мне любимому дважды не писАть!"... вопрос в том, КАК это сделать? как заставить конструктор проинициализировать экземплярные члены класса значениями из соотв. атрибутов DefaultValueAttribute?! |
Ответы | Всего ответов: 4 |
Номер ответа: 1 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() Вопросов: 87 Ответов: 459 |
Профиль | Цитата | #1 | Добавлено: 11.04.06 17:19 |
Хм... похоже, не я один этим вопросом задавался:
на странице http://support.microsoft.com/kb/311339/en-us сказано: MSDN documentation for the DefaultValueAttribute class may be confusing.
... ... However, the DefaultValue attribute does not cause the initial value to be initialized with the attribute's value. Иными словами, нужно явно задавать дефолты в ДВУХ местах - и в атрибуте, и в конструкторе. Вот так. Причём в конструкторе можно читать прямо из метаданных: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconretrievinginformationstoredinattributes.asp (статья "Retrieving Information Stored in Attributes" ![]() Сам спросил - сам ответил ![]() |
Номер ответа: 2 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() Разработчик Offline Client Вопросов: 23 Ответов: 879 |
Web-сайт: Профиль | Цитата | #2 | Добавлено: 11.04.06 18:01 |
Не успел, ответить![]() Именно так, в двух местах. Можно создать перегруженный конструктор для десериализации. c = CType(sf.Deserialize(fs), Class1)
' Конструктор для десериализации
Public Sub New(ByVal info As SerializationInfo, ByVal context As StreamingContext) Me.x = info.GetInt32("IntProp" ![]() Me.y = info.GetString("StrProp" ![]() 'Dim d As Date = info.GetDateTime("TimeStamp" ![]() End Sub |
Номер ответа: 3 Автор ответа: ![]() ![]() ![]() ![]() ![]() Вопросов: 58 Ответов: 4255 ![]() |
Профиль | Цитата | #3 | Добавлено: 11.04.06 21:58 |
Я тоже задавался этой проблемой, но так же ничего не вышло.. Чтобы обойти это, я иницилизирую переменную при объявлении, а не в конструкторе. Хотя, в общем-то, разницы никакой..
Dim c_StrProp As String = "Вася"
|
Номер ответа: 4 Автор ответа: ![]() ![]() ![]() ![]() ![]() ![]() Вопросов: 87 Ответов: 459 |
Профиль | Цитата | #4 | Добавлено: 11.04.06 23:39 |
2vito:
Только вот есть щас задумка инициализировать свойства с их перебором в цикле и с авто-определением типов у каждого, чтобы в конструкторе явно не перечислять все свойства одно за другим и не писАть, где GetInt32, а где GetString. |
Страница: 1 |
|