Tipi di enumerazioni nei contratti dati
Le enumerazioni possono essere espresse nel modello del contratto dati. In questo argomento vengono esaminati molti esempi che spiegano il modello di programmazione.
Nozioni fondamentali sull'enumerazione
Per utilizzare i tipi di enumerazione nel modello del contratto dati, applicare l'attributo DataContractAttribute al tipo. Applicare quindi l'attributo EnumMemberAttribute a ogni membro che deve essere incluso nel contratto dati.
Nell'esempio che segue vengono illustrate due classi. La prima utilizza l'enumerazione e la seconda definisce l'enumerazione.
Un'istanza della classe Car
può essere inviata o ricevuta solo se il campo condition
è impostato su uno dei valori New
, Used
o Rental
. Se condition
è Broken
o Stolen
, viene generata un'eccezione SerializationException.
È possibile utilizzare come al solito le proprietà DataContractAttribute (Name e Namespace) per i contratti dati dell'enumerazione.
Valori membro dell'enumerazione
In genere il contratto dati include i nomi dei membri dell'enumerazione, non i valori numerici. Tuttavia, quando si utilizza il modello del contratto dati, se il lato ricevente è un client WCF, lo schema esportato mantiene i valori numerici. La situazione è diversa quando si utilizza Utilizzo della classe XmlSerializer.
Nell'esempio precedente, se condition
è impostato su Used
e i dati vengono serializzati in XML, il codice XML risultante è <condition>Used</condition>
e non <condition>1</condition>
. Di conseguenza, il contratto dati seguente è equivalente al contratto dati di CarConditionEnum
.
Ad esempio, è possibile utilizzare CarConditionEnum
sul lato mittente e CarConditionWithNumbers
sul lato ricevente. Sebbene il lato mittente utilizza il valore "1" per Used
e il lato ricevente utilizza il valore "20", la rappresentazione XML è <condition>Used</condition>
per entrambi i lati.
Per essere incluso nel contratto dati, è necessario applicare l'attributo EnumMemberAttribute. In .NET Framework, è sempre possibile applicare il valore speciale 0 (zero) a un'enumerazione che è anche il valore predefinito per qualsiasi enumerazione. Tuttavia, anche il valore speciale zero non può essere serializzato a meno che sia contrassegnato con l'attributo EnumMemberAttribute.
Esistono due eccezioni a questo contesto:
- Enumerazioni di flag (esaminate più avanti in questo argomento).
- Membri dati dell'enumerazione con la proprietà EmitDefaultValue impostata su false (in tal caso l'enumerazione con valore zero viene omessa dai dati serializzati).
Personalizzazione dei valori membro dell'enumerazione
È possibile personalizzare il valore del membro dell'enumerazione che costituisce una parte del contratto dati utilizzando la proprietà Value dell'attributo EnumMemberAttribute.
Ad esempio, il contratto dati seguente è equivalente anche al contratto dati di CarConditionEnum
.
Una volta serializzato, il valore di PreviouslyOwned
contiene la rappresentazione XML <condition>Used</condition>
.
Enumerazioni semplici
È anche possibile serializzare i tipi di enumerazione ai quali non è stato applicato l'attributo DataContractAttribute. Tali tipi di enumerazione vengono trattati esattamente come descritto in precedenza, con l'eccezione che ogni membro, a cui non è applicato l'attributo NonSerializedAttribute, viene trattato come se fosse stato applicato l'attributo EnumMemberAttribute. Ad esempio, l'enumerazione seguente contiene implicitamente un contratto dati equivalente all'esempio CarConditionEnum
precedente.
È possibile utilizzare le enumerazioni semplici quando non è necessario personalizzare lo spazio dei nomi e il nome del contratto dati dell'enumerazione e i valori membro dell'enumerazione.
Nota sulle enumerazioni semplici
L'applicazione dell'attributo EnumMemberAttribute alle enumerazioni semplici non produce alcun effetto.
È indifferente se l'attributo SerializableAttribute viene applicato o meno all'enumerazione.
Il fatto che la classe DataContractSerializer si basa sull'applicazione dell'attributo NonSerializedAttribute ai membri dell'enumerazione è diverso dal comportamento di BinaryFormatter e SoapFormatter. Entrambi i serializzatori ignorano l'attributo NonSerializedAttribute.
Enumerazioni di flag
È possibile applicare l'attributo FlagsAttribute alle enumerazioni. In tal caso, è possibile inviare o ricevere simultaneamente un elenco di zero o più valori di enumerazione.
A tale scopo, applicare l'attributo DataContractAttribute all'enumerazione del flag e quindi contrassegnare tutti i membri che sono potenze di due con l'attributo EnumMemberAttribute. Si noti che per utilizzare un'enumerazione del flag, la progressione deve essere una sequenza ininterrotta di potenze di 2 (ad esempio, 1, 2, 4, 8, 16, 32, 64).
I passaggi seguenti si applicano all'invio del valore dell'enumerazione di un flag:
- Tentare di individuare un membro dell'enumerazione (a cui è applicato l'attributo EnumMemberAttribute) associato al valore numerico. Se disponibile, inviare un elenco che contenga solo quel membro.
- Tentare di suddividere il valore numerico in una somma tale che vi siano membri dell'enumerazione (ai quali è applicato l'attributo EnumMemberAttribute) associati a ogni parte della somma. Inviare l'elenco di tutti questi membri. Poiché viene utilizzato l'algoritmo di tipo greedy per trovare tale somma, non è possibile garantire che tale somma venga trovata anche se è presente. Per evitare questo problema, verificare che i valori numerici dei membri dell'enumerazione siano potenze di due.
- Se i due passaggi precedenti hanno esito negativo e il valore numerico è diverso da zero, generare un'eccezione SerializationException. Se il valore numerico è zero, inviare l'elenco vuoto.
Esempio
L'esempio di enumerazione seguente può essere utilizzato in un'operazione di flag.
I valori nell'esempio seguente vengono serializzati come indicato.
Vedere anche
Riferimenti
Concetti
Utilizzo di contratti dati
Specifica del trasferimento di dati nei contratti di servizio