Цель шаблона {propertyName}Specified
описана в Поддержка привязки XML-схемы: поддержка привязки атрибутов MinOccurs . Он был добавлен для поддержки элемента схемы XSD, в котором:
. В этом случае xsd.exe /classes
автоматически сгенерирует (или вы можете вручную создать) свойство с тем же именем, что и элемент схемы, и {propertyName}Specified
boolean get / set property , который отслеживает, был ли элемент встречен в XML и должен быть сериализован обратно в XML. Если этот элемент встречается, {propertyName}Specified
установлен на true
, в противном случае false
, Таким образом, десериализованный экземпляр может определить, было ли свойство отключено (а не явно установлено его значение по умолчанию) в исходном XML.
Обратный также реализуется для генерации схемы. Если вы определяете тип C # с парой свойств, соответствующих шаблону выше, используйте xsd.exe
для создания соответствующего файла XSD, к схеме будет добавлен соответствующий minOccurrs
. Например, задан следующий тип:
public class ExampleClass
{
[XmlElement]
public decimal Something { get; set; }
[XmlIgnore]
public bool SomethingSpecified { get; set; }
}
Будет сгенерирована следующая схема и наоборот:
Обратите внимание, что, хотя xsd.exe
документируется только для автоматически генерирует свойство {propertyName}Specified
для свойств типа значения, XmlSerializer
будет уважать шаблон при использовании вручную для свойств ссылочного типа.
Вы можете спросить, почему xsd.exe
не связывается с Nullable
в этом случае? Возможно, потому что:
xsi:nil="true"
. См. Xsi: nil Поддержка привязки атрибутов . Вам нужно знать этот шаблон, потому что xsd.exe
иногда генерирует его для вас автоматически, однако взаимодействие между свойством и свойством Specified
является странным и способным создавать ошибки. Вы можете заполнить все свойства своего класса, затем сериализовать в XML и потерять все , потому что вы также не установили соответствующие свойства Specified
в true
. Эта «гоча» появляется здесь время от времени здесь, см., Например, этот вопрос или этот тоже .
Еще одна «полученная» с этим шаблоном заключается в том, что если вам нужно сериализовать свой тип с помощью сериализатора, который делает не поддерживайте этот шаблон, вы можете вручную отключить вывод этого свойства во время сериализации и, вероятно, придется вручную установить его во время десериализации. Поскольку каждый сериализатор может иметь свой собственный механизм подавления свойств (или вообще никакого механизма!), Это может стать все более обременительным с течением времени.
(Наконец, я немного удивлен, что ваш MyPropertySpecified
работает без сеттера. Кажется, я вспомнил версию .Net 2.0, в которой отсутствующий установщик {propertyName}Specified
мог бы вызвать исключение, но оно больше не воспроизводится в более поздних версиях, и у меня нет 2.0, чтобы это могло быть третьим.)
Поддержка метода ShouldSerialize{PropertyName}()
задокументирована в Свойствах в элементах управления Windows Forms: определение значений по умолчанию с помощью методов ShouldSerialize и Reset . Как вы можете видеть, документация находится в разделе Windows Forms в MSDN, а не в секции XmlSerializer
, так что это, по сути, полузакрытая функциональность. Я не знаю, почему поддержка этого метода и свойство Specified
существуют в XmlSerializer
. ShouldSerialize
был введен в .Net 1.1 и I считают , что поддержка привязки MinOccurs была добавлена в .Net 2.0 , поэтому, возможно, более ранние функции didn 't вполне удовлетворяет потребности (или вкуса) команды разработчиков xsd.exe
?
Поскольку это метод не является свойством, ему не хватает «gotchas» шаблона {propertyName}Specified
. Он также кажется более популярным на практике и был принят другими сериализаторами, включая:
Итак, какой шаблон использовать?
xsd.exe
автоматически генерирует свойство {propertyName}Specified
, или ваш тип должен отслеживать, появился или нет конкретный элемент в файле XML, или вам нужен автогенератор XSD чтобы указать, что определенное значение является необязательным, используйте этот шаблон и следите за «gotchas». ShouldSerialize{PropertyName}()
. Он имеет меньше ошибок и может быть более широко поддержан. Мне пришлось сбросить настройки. Каким-то образом они испортились, и окно свойств было невозможно просмотреть.