Когда подходит атрибут KnownType?
После чтения ссылки MSDN у меня все еще есть вопросы о том, когда использовать атрибут KnownType. Я понимаю, что атрибут связывает информацию о типе с сериализатором, но когда это необходимо? Является ли уместным, когда сериализуемый класс имеет ссылки на тип базового класса, и существуют ли классы производных производных, которые могут быть установлены для этих ссылок?
Кроме того, есть ли недостатки в чрезмерном использовании атрибута? Например, в предыдущем примере, если сериализованный класс был помечен KnownType (baseClass), хотя была явная ссылка на этот тип?
Ответы
Ответ 1
[KnownType]
необходимо рассказать о подтипах. Недостатком этого не является то, что следующее не будет работать:
[DataContract]
class Foo {}
[DataContract]
class Bar : Foo {}
с помощью метода на интерфейсе WCF, который возвращает:
public Foo GetFoo() { return new Bar(); }
Без атрибута сериализатор (особенно для типов с поддержкой mex/proxy) не будет знать о Bar
, и он не сработает. С атрибутом:
[DataContract, KnownType(typeof(Bar))]
class Foo {}
он будет работать. Это относится только к DataContractSerializer
- при NetDataContractSerializer
вы получаете данные типа по-другому.
Ответ 2
Атрибут KnownType необходим, когда вы сериализуете неконкретные типы, такие как интерфейсы или базовые классы. Сепаратор WCF должен знать обо всех возможных реализациях интерфейса или унаследованного класса. Любые реализации, о которых он не знает, вызовут исключение сериализации.
В этом SO-вопросе можно найти одно возможное использование
Ответ 3
Если вы используете XSD "наследование" в своей схеме.
У вас есть это назад; KnownTypeAttribute применяется к базовому классу и называет все производные классы, которые могут быть переданы как ссылка на базу.
Например:
...
KnownType(typeof(POBoxAddress))
KnownType(typeof(StreetAddress))
KnownType(typeof(SingleLineAddress))
KnownType(typeof(ParsedAddress))
public abstract class AddressBase
{
...
}