2010-07-02 9 views
37

Dopo aver letto il riferimento MSDN, ho ancora domande su quando utilizzare l'attributo KnownType. Capisco che l'attributo comunichi le informazioni sul tipo al serializzatore, ma quando è necessario? È appropriato quando la classe serializzata ha riferimenti di un tipo di classe base e ci sono classi derivate up-cast che potrebbero essere impostate su quei riferimenti?Quando è opportuno utilizzare l'attributo KnownType?

Inoltre, ci sono degli svantaggi nell'uso eccessivo dell'attributo? Ad esempio, nell'esempio precedente, se la classe serializzata era contrassegnata con KnownType (baseClass) anche se c'era un riferimento esplicito a quel tipo?

risposta

58

[KnownType] è necessario per dire di lui circa sottotipi. Lo svantaggio di non utilizzo è che il seguente non funzionerà:

[DataContract] 
class Foo {} 

[DataContract] 
class Bar : Foo {} 

con un metodo sull'interfaccia WCF che restituisce:

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

Senza l'attributo, il serializzatore (soprattutto per mex/proxy-generated types) non saprà nulla di Bar e fallirà. Con l'attributo:

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

si sarà lavoro. Questo vale solo per DataContractSerializer - con NetDataContractSerializer si ottiene il tipo di dati in un modo diverso.

+1

dolce! Ottimo esempio anche. Grazie! – bwerks

6

L'attributo KnownType è necessario quando si serializzano tipi non concreti come interfacce o classi base. Il serializzatore WCF deve conoscere tutte le possibili implementazioni dell'interfaccia o della classe ereditata. Qualsiasi implementazione di cui non è a conoscenza causerà un'eccezione di serializzazione.

Un uso possable può essere trovato in questo SO question

5

Se si utilizza "ereditarietà" XSD nello schema.

Hai indietro; il KnownTypeAttribute viene applicato alla classe base e nomina tutte le classi derivate che potrebbero essere passate come riferimento alla base.

Per esempio:

... 
KnownType(typeof(POBoxAddress)) 
KnownType(typeof(StreetAddress)) 
KnownType(typeof(SingleLineAddress)) 
KnownType(typeof(ParsedAddress)) 
public abstract class AddressBase 
{ 
    ... 
} 
Problemi correlati