Dela via


Ekvivalens för datakontrakt

För att en klient ska kunna skicka data av en viss typ till en tjänst, eller en tjänst för att skicka data till en klient, behöver den skickade typen inte nödvändigtvis finnas på mottagarsidan. Det enda kravet är att datakontrakten för båda typerna är likvärdiga. (Ibland krävs inte strikt likvärdighet, vilket beskrivs i Versionshantering av datakontrakt.)

För att datakontrakt ska vara likvärdiga måste de ha samma namnområde och namn. Dessutom måste varje datamedlem på ena sidan ha en motsvarande datamedlem på den andra sidan.

För att datamedlemmar ska vara likvärdiga måste de ha samma namn. Dessutom måste de representera samma typ av data. deras datakontrakt måste alltså vara likvärdiga.

Kommentar

Observera att namn och namnområden för datakontrakt samt datamedlemsnamn är skiftlägeskänsliga.

Mer information om namn och namnområden för datakontrakt samt namn på datamedlemmar finns i Namn på datakontrakt.

Om det finns två typer på samma sida (avsändare eller mottagare) och deras datakontrakt inte är likvärdiga (till exempel har de olika datamedlemmar), bör du inte ge dem samma namn och namnområde. Detta kan leda till att undantag utlöses.

Datakontrakten för följande typer är likvärdiga:

[DataContract]
public class Customer
{
    [DataMember]
    public string fullName;

    [DataMember]
    public string telephoneNumber;
}

[DataContract(Name = "Customer")]
public class Person
{
    [DataMember(Name = "fullName")]
    private string nameOfPerson;

    private string address;

    [DataMember(Name = "telephoneNumber")]
    private string phoneNumber;
}
<DataContract()> _
Public Class Customer

    <DataMember()> _
    Public fullName As String

    <DataMember()> _
    Public telephoneNumber As String
End Class

<DataContract(Name:="Customer")> _
Public Class Person

    <DataMember(Name:="fullName")> _
    Private nameOfPerson As String

    Private address As String

    <DataMember(Name:="telephoneNumber")> _
    Private phoneNumber As String
End Class

Datamedlemsordning och datakontraktsjämlikhet

Order Användning av egenskapen för klassen kan påverka datakontraktets DataMemberAttribute likvärdighet. Datakontrakten måste ha medlemmar som visas i samma ordning för att vara likvärdiga. Standardordningen är alfabetisk. Mer information finns i Datamedlemsordning.

Följande kod resulterar till exempel i motsvarande datakontrakt.

[DataContract(Name = "Coordinates")]
public class Coords1
{
    [DataMember]
    public int X;
    [DataMember]
    public int Y;
    // Order is alphabetical (X,Y).
}

[DataContract(Name = "Coordinates")]
public class Coords2
{
    [DataMember]
    public int Y;
    [DataMember]
    public int X;
    // Order is alphabetical (X,Y), equivalent
    // to the preceding code.
}

[DataContract(Name = "Coordinates")]
public class Coords3
{
    [DataMember(Order = 2)]
    public int Y;
    [DataMember(Order = 1)]
    public int X;
    // Order is according to the Order property (X,Y),
    // equivalent to the preceding code.
}
<DataContract(Name:="Coordinates")> _
Public Class Coords1
    <DataMember()> _
    Public X As Integer
    <DataMember()> _
    Public Y As Integer
    ' Order is alphabetical (X,Y).
End Class

<DataContract(Name:="Coordinates")> _
Public Class Coords2

    <DataMember()> _
    Public Y As Integer
    <DataMember()> _
    Public X As Integer
    ' Order is alphabetical (X,Y), equivalent 
    ' to the preceding code.
End Class

<DataContract(Name:="Coordinates")> _
Public Class Coords3
    <DataMember(Order:=2)> _
    Public Y As Integer
    <DataMember(Order:=1)> _
    Public X As Integer
    ' Order is according to the Order property (X,Y), 
    ' equivalent to the preceding code.
End Class

Följande resulterar dock inte i ett motsvarande datakontrakt.

[DataContract(Name = "Coordinates")]
public class Coords4
{
    [DataMember(Order = 1)]
    public int Y;
    [DataMember(Order = 2)]
    public int X;
    // Order is according to the Order property (Y,X),
    // different from the preceding code.
}
<DataContract(Name:="Coordinates")> _
Public Class Coords4

    <DataMember(Order:=1)> _
    Public Y As Integer
    <DataMember(Order:=2)> _
    Public X As Integer
    ' Order is according to the Order property (Y,X), 
    ' different from the preceding code.
End Class

Arv, gränssnitt och ekvivalens för datakontrakt

Vid fastställande av likvärdighet behandlas ett datakontrakt som ärver från ett annat datakontrakt som om det bara är ett datakontrakt som innehåller alla datamedlemmar från bastypen. Tänk på att ordningen på datamedlemmarna måste matcha och att bastypsmedlemmar föregår medlemmar av härledd typ i ordningen. Om två datamedlemmar, som i följande kodexempel, har samma ordervärde, är ordningen för dessa datamedlemmar alfabetisk. Mer information finns i Datamedlemsordning.

I följande exempel motsvarar datakontraktet för typen Employee datakontraktet för typen Worker.

[DataContract]
public class Person
{
    [DataMember]
    public string name;
}
[DataContract]
public class Employee : Person
{
    [DataMember]
    public int department;
    [DataMember]
    public string title;
    [DataMember]
    public int salary;
}
// Order is "name", "department", "salary", "title"
// (base class first, then alphabetical).

[DataContract(Name = "Employee")]
public class Worker
{
    [DataMember(Order = 1)]
    public string name;
    [DataMember(Order = 2)]
    public int department;
    [DataMember(Order = 2)]
    public string title;
    [DataMember(Order = 2)]
    public int salary;
}
// Order is "name", "department", "salary", "title"
// (Order=1 first, then Order=2 in alphabetical order),
// which is equivalent to the Employee order}.
<DataContract()> _
Public Class Person
    <DataMember()> Public name As String
End Class

<DataContract()> _
Public Class Employee
    Inherits Person
    <DataMember()> Public department As Integer
    <DataMember()> Public title As String
    <DataMember()> Public salary As Integer
End class

' Order is "name", "department", "salary", "title" 
' (base class first, then alphabetical).

<DataContract(Name:="Employee")> _
Public Class Worker

    <DataMember(Order:=1)> _
    Public name As String
    <DataMember(Order:=2)> _
    Public department As Integer
    <DataMember(Order:=2)> _
    Public title As String
    <DataMember(Order:=2)> _
    Public salary As Integer
End Class
' Order is "name", "department", "salary", "title" 
' (Order=1 first, then Order=2 in alphabetical order), 
' which is equivalent to the Employee order}.

När parametrar och returvärden skickas mellan en klient och en tjänst kan ett datakontrakt från en basklass inte skickas när den mottagande slutpunkten förväntar sig ett datakontrakt från en härledd klass. Detta är i enlighet med objektorienterade programmeringssatser. I föregående exempel går det inte att skicka ett objekt av typen Person när ett Employee är förväntat.

Ett datakontrakt från en härledd klass kan skickas när ett datakontrakt från en basklass förväntas, men bara om den mottagande slutpunkten "känner" till den härledda typen med hjälp av KnownTypeAttribute. Mer information finns i Kända typer av datakontrakt. I föregående exempel kan ett objekt av typen Employee skickas när ett Person är förväntat, men bara om mottagarkoden använder KnownTypeAttribute för att inkludera det i listan över kända typer.

När du skickar parametrar och returnerar värden mellan program, om den förväntade typen är ett gränssnitt, motsvarar det att den förväntade typen är av typen Object. Eftersom varje typ slutligen härleds från Objecthärleds varje datakontrakt i slutändan från datakontraktet för Object. Därför kan alla datakontraktstyper skickas när ett gränssnitt förväntas. Ytterligare steg krävs för att fungera med gränssnitt. Mer information finns i Kända typer av datakontrakt.

Se även