Рекомендуется ли создавать исключения в свойстве с примененным атрибутом DataMember?
DataContract
а также DataMember
атрибуты могут также использоваться для сериализации объекта в файл и для десериализации, используя DataContractSerializer
, Предположим, у нас есть класс со следующим приватным полем и публичным свойством.
public class MyClass
{
private int positiveValue;
public int PositiveValue
{
get { return positiveValue; }
set
{
if (value < 1)
throw new ArgumentOutOfBoundException(...);
positiveValue = value;
}
}
}
Теперь предположим, что у нас есть XML-файл, содержащий состояние ранее сериализованного объекта, и предположим, что пользователь изменил этот файл, указав неверное значение (которое не является положительным значением) для PositiveValue
имущество. Во время десериализации будет выдано исключение, так как значение в файле недопустимо.
Предположим, мы хотим десериализовать список MyClass
объекты из файла: если какой-либо объект недопустим, выдается исключение. Можно ли убедиться, что DataContractSerializer
игнорирует недействительные объекты? Кроме того, принимая во внимание только что объясненную проблему, рекомендуется ли создавать исключения в свойстве с примененным атрибутом DataMember?
2 ответа
С точки зрения списка, нет, вы не можете заставить DCS игнорировать недопустимые объекты. Если возникает исключение, вся десериализация прерывается. Если он не выбрасывает, он будет добавлен в ваш список.
Я хотел бы рассмотреть проверку достоверности после и отдельно от десериализации. В некоторых случаях вы можете просто сказать "игнорировать недопустимые элементы в списках", но, честно говоря, в большинстве случаев, если есть какая-либо проблема, вы просто хотите отказаться от всего этого.
Если вы хотите проверять данные при настройке свойств, но хотите обойти эти проверки во время десериализации, вы можете пометить вспомогательное поле свойства с помощью DataMemberAttribute
вместо собственности. Это приведет к DataContractSerializer
установить значение непосредственно в поле (не в свойстве) и не выдавать никаких проверочных исключений.
[DataMember]
private int positiveValue;
public int PositiveValue
{
get { return positiveValue; }
set
{
if (value < 1)
throw new ArgumentOutOfBoundException(...);
positiveValue = value;
}
}
Обратите внимание, что вспомогательное поле может быть приватным (в противном случае свойство не имело бы особого смысла). Это прекрасно работает с DataContractSerializer
,
Кроме того, принимая во внимание только что объясненную проблему, рекомендуется ли создавать исключения в свойстве с примененным атрибутом DataMember?
Это зависит от того, хотите ли вы, чтобы в вашем приложении были объекты с недействительными данными. Преимущество запрета на установку недействительных данных состоит в том, что вам не нужно проверять объект каждый раз, когда вы его используете, но в этом случае вы должны проверять любой пользовательский ввод и быть готовым к исключениям при загрузке данных. Однако я не думаю, что выбрасывать исключения в свойствах элементов данных неправильно. Это просто вопрос дизайнерского решения.