2010-07-02 36 views
37

Po przeczytaniu referencji MSDN nadal mam pytania dotyczące używania atrybutu KnownType. Rozumiem, że atrybut przekazuje informacje o typie do serializera, ale kiedy to jest potrzebne? Czy jest to właściwe, gdy klasa, która jest serializowana, ma odniesienia do typu klasy bazowej, i czy istnieją klasy pochodne z wyprzedzeniem, które można ustawić na te odniesienia?Kiedy należy używać atrybutu KnownType?

Ponadto, czy są jakieś wady nadużywania atrybutu? Na przykład w poprzednim przykładzie, jeśli zserializowana klasa została oznaczona klasą KnownType (baseClass), mimo że istniało wyraźne odniesienie do tego typu?

Odpowiedz

58

[KnownType] jest potrzebne, aby poinformować go o podtypów. Wadą nie użyciem jest to, że dodaje się nie działać:

[DataContract] 
class Foo {} 

[DataContract] 
class Bar : Foo {} 

ze sposobem na interfejsie WCF zwrócone:

public Foo GetFoo() { return new Bar(); } 

Bez atrybutów a Serializatora (szczególnie dla typy generowane przez mex/proxy) nie będzie wiedział o Bar, a to się nie powiedzie. Z atrybutem:

[DataContract, KnownType(typeof(Bar))] 
class Foo {} 

nim będzie pracy. Dotyczy to tylko DataContractSerializer - z NetDataContractSerializer otrzymujesz dane typu w inny sposób.

+1

słodkie! Świetny przykład. Dzięki! – bwerks

6

Atrybut KnownType jest niezbędny w przypadku serializacji nie-betonowych typów, takich jak interfejsy lub klasy bazowe. Serializator WCF musi wiedzieć o wszystkich możliwych implementacjach interfejsu lub odziedziczonej klasy. Wszelkie implementacje, o których nie wie, spowodują wyjątek serializacji.

Jeden possable użycia można znaleźć w tym SO question

5

Jeśli używasz XSD "dziedziczenia" w swoim schemacie.

Masz go od tyłu; Klasa KnownTypeAttribute jest stosowana do klasy bazowej i określa wszystkie pochodne klasy, które mogą być przekazywane jako odniesienia do bazy.

Na przykład:

... 
KnownType(typeof(POBoxAddress)) 
KnownType(typeof(StreetAddress)) 
KnownType(typeof(SingleLineAddress)) 
KnownType(typeof(ParsedAddress)) 
public abstract class AddressBase 
{ 
    ... 
} 
Powiązane problemy