Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Enumerationen können im Datenvertragsmodell ausgedrückt werden. In diesem Thema werden mehrere Beispiele erläutert, die das Programmiermodell erläutern.
Enumerationsgrundlagen
Eine Möglichkeit zum Verwenden von Enumerationstypen im Datenvertragsmodell besteht darin, das DataContractAttribute Attribut auf den Typ anzuwenden. Anschließend müssen Sie das EnumMemberAttribute Attribut auf jedes Mitglied anwenden, das im Datenvertrag enthalten sein muss.
Das folgende Beispiel zeigt zwei Klassen. Die erste verwendet die Aufzählung und die zweite definiert die Enumeration.
[DataContract]
public class Car
{
[DataMember]
public string model;
[DataMember]
public CarConditionEnum condition;
}
[DataContract(Name = "CarCondition")]
public enum CarConditionEnum
{
[EnumMember]
New,
[EnumMember]
Used,
[EnumMember]
Rental,
Broken,
Stolen
}
<DataContract()> _
Public Class Car
<DataMember()> _
Public model As String
<DataMember()> _
Public condition As CarConditionEnum
End Class
<DataContract(Name:="CarCondition")> _
Public Enum CarConditionEnum
<EnumMember> NewCar
<EnumMember> Used
<EnumMember> Rental
Broken
Stolen
End Enum
Eine Instanz der Car Klasse kann nur gesendet oder empfangen werden, wenn das condition Feld auf einen der Werte New, Used oder Rental gesetzt ist. Wenn condition den Wert Broken oder Stolen hat, wird eine SerializationException ausgelöst.
Sie können die DataContractAttribute Eigenschaften (Name und Namespace) wie üblich für Enumerationsdatenverträge verwenden.
Enumerationsmemberwerte
Im Allgemeinen enthält der Datenvertrag die Namen von Enumerationsmitgliedern und nicht numerische Werte. Wenn die empfangende Seite jedoch ein WCF-Client ist, behält das exportierte Schema bei Verwendung des Datenvertragsmodells die numerischen Werte bei. Beachten Sie, dass dies bei Verwendung der XmlSerializer-Klasse nicht der Fall ist.
Wenn im vorherigen Beispiel condition auf Used festgelegt ist und die Daten in XML serialisiert werden, ist der resultierende XML-Code <condition>Used</condition> und nicht <condition>1</condition>. Daher entspricht der folgende Datenvertrag dem Datenvertrag von CarConditionEnum.
[DataContract(Name = "CarCondition")]
public enum CarConditionWithNumbers
{
[EnumMember]
New = 10,
[EnumMember]
Used = 20,
[EnumMember]
Rental = 30,
}
<DataContract(Name:="CarCondition")> _
Public Enum CarConditionWithNumbers
<EnumMember> NewCar = 10
<EnumMember> Used = 20
<EnumMember> Rental = 30
End Enum
Zum Beispiel können Sie CarConditionEnum auf der Sendeseite und CarConditionWithNumbers auf der Empfangsseite verwenden. Obwohl die sendende Seite den Wert "1" für Used und die empfangende Seite den Wert "20" verwendet, ist <condition>Used</condition> die XML-Darstellung für beide Seiten.
Um in den Datenvertrag aufgenommen zu werden, müssen Sie das EnumMemberAttribute Attribut anwenden. Im .NET Framework können Sie immer den Sonderwert 0 (Null) auf eine Enumeration anwenden, die auch der Standardwert für jede Enumeration ist. Selbst dieser spezielle Nullwert kann jedoch nicht serialisiert werden, es sei denn, er ist mit dem EnumMemberAttribute Attribut gekennzeichnet.
Es gibt zwei Ausnahmen:
Flagenumerationen (weiter unten in diesem Thema beschrieben).
Enumerationsdatenmitglieder, bei denen die EmitDefaultValue Eigenschaft auf
falsefestgelegt ist (in diesem Fall wird die Enumeration mit dem Wert 0 aus den Daten der Serialisierung weggelassen).
Anpassen von Enumerationsmemberwerten
Mit der Value Eigenschaft des EnumMemberAttribute Attributs können Sie den Enumerationsmitgliederwert anpassen, der Teil des Datenvertrags ist.
Der folgende Datenvertrag entspricht beispielsweise auch dem Datenvertrag des CarConditionEnum.
[DataContract(Name = "CarCondition")]
public enum CarConditionWithDifferentNames
{
[EnumMember(Value = "New")]
BrandNew,
[EnumMember(Value = "Used")]
PreviouslyOwned,
[EnumMember]
Rental
}
<DataContract(Name:="CarCondition")> _
Public Enum CarConditionWithDifferentNames
<EnumMember(Value:="New")> BrandNew
<EnumMember(Value:="Used")> PreviouslyOwned
<EnumMember> Rental
End Enum
Beim Serialisieren wird der Wert PreviouslyOwned durch die XML-Darstellung <condition>Used</condition> repräsentiert.
Einfache Enumerationen
Sie können auch Enumerationstypen serialisieren, auf die das DataContractAttribute Attribut nicht angewendet wurde. Solche Enumerationstypen werden genau wie zuvor beschrieben behandelt, mit der Ausnahme, dass jedes Element (für das das NonSerializedAttribute Attribut nicht angewendet wurde) so behandelt wird, als ob das EnumMemberAttribute Attribut angewendet wurde. Die folgende Aufzählung weist beispielsweise implizit einen Datenvertrag auf, der dem vorherigen CarConditionEnum Beispiel entspricht.
public enum CarCondition
{
New,
Used,
Rental,
[NonSerialized]
Lost
}
Public Enum CarCondition
[New]
Used
Rental
End Enum
Sie können einfache Enumerationen verwenden, wenn Sie den Datenvertragsnamen und den Namespace und die Enumerationsmemmwerte nicht anpassen müssen.
Hinweise zu einfachen Enumerationen
Das Anwenden des EnumMemberAttribute Attributs auf einfache Enumerationen hat keine Auswirkung.
Es macht keinen Unterschied, ob das SerializableAttribute Attribut auf die Enumeration angewendet wird.
Die Tatsache, dass die DataContractSerializer Klasse das NonSerializedAttribute Attribut, das auf Enumerationsmitglieder angewendet wird, berücksichtigt, unterscheidet sich vom Verhalten des BinaryFormatter und des SoapFormatter. Beide Serialisierer ignorieren das NonSerializedAttribute Attribut.
Flagenumerationen
Sie können das FlagsAttribute Attribut auf Enumerationen anwenden. In diesem Fall kann eine Liste mit Null- oder mehr Enumerationswerten gleichzeitig gesendet oder empfangen werden.
Wenden Sie dazu das DataContractAttribute-Attribut auf die Flagenumeration an, und markieren Sie dann alle Member, die Potenzen von 2 sind, mit dem EnumMemberAttribute-Attribut. Beachten Sie, dass für die Verwendung einer Flag-Enumeration die Reihe eine ununterbrochene Abfolge von Zweierpotenzen sein muss (z. B. 1, 2, 4, 8, 16, 32, 64).
Die folgenden Schritte gelten für das Senden des Enumerationswerts eines Flags:
Versuchen Sie, ein Enumerationselement (mit angewendetem EnumMemberAttribute Attribut) zu finden, das dem numerischen Wert zugeordnet ist. Wenn gefunden, senden Sie eine Liste, die nur dieses Element enthält.
Versuchen Sie, den numerischen Wert in eine Summe aufzuteilen, sodass es Enumerationsmitglieder gibt, die jedem Teil der Summe zugeordnet sind und jeweils mit dem EnumMemberAttribute-Attribut versehen sind. Senden Sie die Liste aller diese Mitglieder. Beachten Sie, dass der Gieralgorithmus verwendet wird, um eine solche Summe zu finden, und somit gibt es keine Garantie dafür, dass eine solche Summe gefunden wird, auch wenn sie vorhanden ist. Um dieses Problem zu vermeiden, stellen Sie sicher, dass die numerischen Werte der Enumerationsmitglieder Zweierpotenzen sind.
Wenn die beiden vorherigen Schritte fehlschlagen und der numerische Wert ungleich Null ist, wird ein SerializationException ausgelöst. Wenn der numerische Wert null ist, senden Sie die leere Liste.
Beispiel
Das folgende Enumerationsbeispiel kann in einem Flag-Vorgang verwendet werden.
[DataContract][Flags]
public enum CarFeatures
{
None = 0,
[EnumMember]
AirConditioner = 1,
[EnumMember]
AutomaticTransmission = 2,
[EnumMember]
PowerDoors = 4,
AlloyWheels = 8,
DeluxePackage = AirConditioner | AutomaticTransmission | PowerDoors | AlloyWheels,
[EnumMember]
CDPlayer = 16,
[EnumMember]
TapePlayer = 32,
MusicPackage = CDPlayer | TapePlayer,
[EnumMember]
Everything = DeluxePackage | MusicPackage
}
<DataContract(), Flags()> _
Public Enum CarFeatures
None = 0
<EnumMember> AirConditioner = 1
<EnumMember> AutomaticTransmission = 2
<EnumMember> PowerDoors = 4
AlloyWheels = 8
DeluxePackage = AirConditioner Or AutomaticTransmission Or PowerDoors Or AlloyWheels
<EnumMember> CDPlayer = 16
<EnumMember> TapePlayer = 32
MusicPackage = CDPlayer Or TapePlayer
<EnumMember> Everything = DeluxePackage Or MusicPackage
End Enum
Die folgenden Beispielwerte werden wie angegeben serialisiert.
CarFeatures cf1 = CarFeatures.AutomaticTransmission;
//Serialized as <cf1>AutomaticTransmission</cf1>
CarFeatures cf2 = (CarFeatures)5;
//Serialized as <cf2>AirConditioner PowerDoors</cf2> since 5=1+4
CarFeatures cf3 = CarFeatures.MusicPackage;
//Serialized as <cf3>CDPlayer TapePlayer</cf3> since MusicPackage itself is not an EnumMember
CarFeatures cf4 = CarFeatures.Everything;
//Serialized as <cf4>Everything</cf4> since Everything itself is an EnumMember
CarFeatures cf5 = CarFeatures.DeluxePackage;
//Throws a SerializationException since neither DeluxePackage nor AlloyWheels are EnumMembers
CarFeatures cf6 = CarFeatures.None;
//Serialized as the empty list <cf6></cf6> since there is no EnumMember mapped to zero
Private cf1 As CarFeatures = CarFeatures.AutomaticTransmission
'Serialized as <cf1>AutomaticTransmission</cf1>
Private cf2 As CarFeatures = ctype(5, CarFeatures)
'Serialized as <cf2>AirConditioner PowerDoors</cf2> since 5=1+4
Private cf3 As CarFeatures = CarFeatures.MusicPackage
'Serialized as <cf3>CDPlayer TapePlayer</cf3> since MusicPackage
' itself is not an EnumMember.
Private cf4 As CarFeatures = CarFeatures.Everything
'Serialized as <cf4>Everything</cf4> since Everything itself is an EnumMember.
Private cf5 As CarFeatures = CarFeatures.DeluxePackage
'Throws a SerializationException since neither DeluxePackage nor
' AlloyWheels are EnumMembers.
Private cf6 As CarFeatures = CarFeatures.None
'Serialized as the empty list <cf6></cf6> since there is no EnumMember mapped to zero.