Когда целесообразно использовать атрибут KnownType? - PullRequest
43 голосов
/ 02 июля 2010

После прочтения справочника MSDN у меня все еще остаются вопросы о том, когда использовать атрибут KnownType. Я понимаю, что атрибут передает информацию о типе сериализатору, но когда это необходимо? Уместно ли, когда сериализуемый класс имеет ссылки на тип базового класса, и существуют производные классы с повышением, которые могут быть установлены для этих ссылок?

Кроме того, есть ли недостатки в использовании атрибута? Например, в предыдущем примере, если сериализованный класс был помечен с помощью KnownType (baseClass), хотя существовала явная ссылка на этот тип?

Ответы [ 4 ]

65 голосов
/ 02 июля 2010

[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 вы получаете данные типа другим способом.

7 голосов
/ 02 июля 2010

Если вы используете XSD «наследование» в вашей схеме.

Вы получили это задом наперед; атрибут KnownTypeAttribute применяется к базовому классу и именует все производные классы, которые могут быть переданы в качестве ссылки на базовый класс.

Например:

...
KnownType(typeof(POBoxAddress))
KnownType(typeof(StreetAddress))
KnownType(typeof(SingleLineAddress))
KnownType(typeof(ParsedAddress))
public abstract class AddressBase
{
    ...
}
6 голосов
/ 02 июля 2010

Атрибут KnownType необходим при сериализации неконкретных типов, таких как интерфейсы или базовые классы. Сериализатор WCF должен знать обо всех возможных реализациях интерфейса или унаследованного класса. Любые реализации, о которых он не знает, вызовут исключение сериализации.

В этом ТАМ вопросе

можно найти одно возможное использование
0 голосов
/ 23 марта 2018

Это также полезно для случаев, подобных приведенным ниже:

[DataContract]
[knownType(typeof(Person))]
public class KeyValue
{
  [DataMember]
  public string key {get; set;}

  [DataMember]
  public string value {get; set;}

  // rest of the code
}

теперь предположим, что значение содержит некоторый объект другого класса, скажем Person.тогда это все для работы, вы должны добавить knownType (typeof (Person))

...