Ekvivalence kontraktů dat

Aby klient mohl úspěšně odesílat data určitého typu do služby nebo aby služba úspěšně odeslala data klientovi, nemusí odeslaný typ nutně existovat na přijímající straně. Jediným požadavkem je, aby datové kontrakty obou typů byly ekvivalentní. (Někdy se nevyžaduje striktní ekvivalence, jak je popsáno v tématuSpráva verzí kontraktů dat.)

Aby kontrakty dat byly ekvivalentní, musí mít stejný obor názvů a název. Každý datový člen na jedné straně navíc musí mít na druhé straně ekvivalentní datový člen.

Aby datové členy byly ekvivalentní, musí mít stejný název. Kromě toho musí představovat stejný typ dat; to znamená, že jejich datové kontrakty musí být ekvivalentní.

Poznámka:

Všimněte si, že názvy kontraktů dat a obory názvů, stejně jako názvy členů dat, rozlišují malá a velká písmena.

Další informace o názvech kontraktů dat a oborech názvů a také o názvech členů dat naleznete v tématu Názvy kontraktů dat.

Pokud existují dva typy na stejné straně (odesílatel nebo příjemce) a jejich datové kontrakty nejsou ekvivalentní (například mají různé datové členy), neměli byste jim dát stejný název a obor názvů. To může způsobit vyvolání výjimek.

Kontrakty dat pro následující typy jsou ekvivalentní:

[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

Pořadí datových členů a ekvivalence kontraktů dat

Order Použití vlastnosti DataMemberAttribute třídy může mít vliv na ekvivalenci kontraktů dat. Kontrakty dat musí mít členy, které se zobrazují ve stejném pořadí, aby byly ekvivalentní. Výchozí pořadí je abecední. Další informace naleznete v tématu Pořadí datových členů.

Následující kód například vede k ekvivalentním datovým kontraktům.

[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

Následující však nemá za následek ekvivalentní kontrakt dat.

[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

Dědičnost, rozhraní a ekvivalence kontraktů dat

Při určování ekvivalence je datový kontrakt, který dědí z jiného datového kontraktu, považován za jeden datový kontrakt, který zahrnuje všechny datové členy ze základního typu. Mějte na paměti, že pořadí datových členů musí odpovídat členům základního typu před odvozené členy v pořadí. Pokud mají navíc dva datové členy stejnou hodnotu pořadí, jako v následujícím příkladu kódu, pořadí těchto datových členů je abecední. Další informace naleznete v tématu Pořadí datových členů.

V následujícím příkladu je datový kontrakt pro typ Employee ekvivalentní datovému kontraktu pro typ 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}.

Při předávání parametrů a návratových hodnot mezi klientem a službou nelze odeslat datový kontrakt ze základní třídy, když přijímající koncový bod očekává kontrakt dat z odvozené třídy. To je v souladu s objektově orientovanými programovacími tenety. V předchozím příkladu nelze odeslat objekt typu Person , pokud Employee je očekávána.

Datový kontrakt z odvozené třídy lze odeslat, když je očekáván datový kontrakt ze základní třídy, ale pouze v případě, že přijímající koncový bod "ví" odvozeného typu pomocí KnownTypeAttribute. Další informace naleznete v tématu Známé typy kontraktů dat. V předchozím příkladu lze odeslat objekt typu Employee , pokud Person je očekávána, ale pouze v případě, že kód příjemce použije KnownTypeAttribute k jeho zahrnutí do seznamu známých typů.

Při předávání parametrů a návratových hodnot mezi aplikacemi, pokud je očekávaný typ rozhraní, je ekvivalentní očekávanému typu typu Object. Vzhledem k tomu, že každý typ nakonec pochází z Object, každá datová smlouva nakonec pochází z datového kontraktu pro Object. Proto lze předat jakýkoli datový typ kontraktu, pokud je očekáváno rozhraní. K úspěšné práci s rozhraními jsou vyžadovány další kroky; Další informace naleznete v tématu Známé typy kontraktů dat.

Viz také