После чтения ссылки MSDN у меня все еще есть вопросы о том, когда использовать атрибут KnownType. Я понимаю, что атрибут передает информацию о типе к сериализатору, но когда это необходимо? Действительно ли уместно, когда сериализируемый класс имеет ссылки типа базового класса, и существуют восходящие производные классы, которые могли быть установлены на те ссылки?
Кроме того, там какие-либо недостатки к злоупотреблению атрибута? Например, в предыдущем примере, если сериализированный класс был отмечен с KnownType (базовый класс) даже при том, что была прямая ссылка на тот тип?
[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
вы получаете данные типа другим способом.
Если вы используете XSD «наследование» в своей схеме.
Вы получили это наоборот; Атрибут KnownTypeAttribute применяется к базовому классу и называет все производные классы, которые могут быть переданы в качестве ссылки на базовый.
Например:
...
KnownType(typeof(POBoxAddress))
KnownType(typeof(StreetAddress))
KnownType(typeof(SingleLineAddress))
KnownType(typeof(ParsedAddress))
public abstract class AddressBase
{
...
}
Атрибут KnownType необходим при сериализации неконкретных типов, таких как интерфейсы или базовые классы. Сериализатор WCF должен знать обо всех возможных реализациях интерфейса или унаследованного класса. Любые реализации, о которых он не знает, вызовут исключение сериализации.
Одно возможное использование можно найти в этом вопросе SO