Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 |

 

  Вопрос: Десериализация и DefaultValueAttribute Добавлено: 11.04.06 16:31  

Автор вопроса:  Comanche
Допустим, имею класс с двумя свойствами:

    <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
Автор ответа:
 Comanche



Вопросов: 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
Автор ответа:
 vito



Разработчик Offline Client

Вопросов: 23
Ответов: 879
 Web-сайт: softvito.narod2.ru
 Профиль | | #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
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #3 Добавлено: 11.04.06 21:58
Я тоже задавался этой проблемой, но так же ничего не вышло.. Чтобы обойти это, я иницилизирую переменную при объявлении, а не в конструкторе. Хотя, в общем-то, разницы никакой..
Dim c_StrProp As String = "Вася"

Ответить

Номер ответа: 4
Автор ответа:
 Comanche



Вопросов: 87
Ответов: 459
 Профиль | | #4 Добавлено: 11.04.06 23:39
2vito:
Только вот есть щас задумка инициализировать свойства с их перебором в цикле и с авто-определением типов у каждого, чтобы в конструкторе явно не перечислять все свойства одно за другим и не писАть, где GetInt32, а где GetString.

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам