次の方法で共有


データ コントラクトの等価性

クライアントが特定の種類のデータをサービスに正常に送信したり、サービスからクライアントにデータを正常に送信したりするには、送信された型が受信側に必ずしも存在する必要はありません。 唯一の要件は、両方の型のデータ コントラクトが同等であるということです。 (場合によっては、「 データ コントラクトのバージョン管理」で説明されているように、厳密な等価性は必要ありません)。

データ コントラクトを同等にするには、同じ名前空間と名前を持つ必要があります。 さらに、一方の側の各データ メンバーには、もう一方の側に同等のデータ メンバーが必要です。

データ メンバーを同等にするには、同じ名前を持つ必要があります。 さらに、同じ種類のデータを表す必要があります。つまり、データ コントラクトは同等である必要があります。

データ コントラクト名と名前空間、およびデータ メンバー名は、大文字と小文字を区別します。

データ コントラクト名と名前空間、およびデータ メンバー名の詳細については、「 データ コントラクト名」を参照してください。

2 つの型が同じ側 (送信側または受信側) に存在し、それらのデータ コントラクトが等しくない場合 (たとえば、データ メンバーが異なる場合)、同じ名前と名前空間を指定しないでください。 同じ名前と名前空間を使用すると、例外がスローされる可能性があります。

次の型のデータ コントラクトは同等です。

[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

データ メンバーの順序とデータ コントラクトの等価性

Order クラスの DataMemberAttribute プロパティを使用すると、データ コントラクトの等価性に影響する可能性があります。 データ コントラクトには、同等の順序で表示されるメンバーが必要です。 既定の順序はアルファベット順です。 詳細については、「 データ メンバーの順序」を参照してください。

たとえば、次のコードは同等のデータ コントラクトになります。

[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

ただし、次の場合、同等のデータ コントラクトは生成されません。

[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

継承、インターフェイス、およびデータ コントラクトの等価性

等価性を決定する場合、別のデータ コントラクトから継承するデータ コントラクトは、基本型のすべてのデータ メンバーを含む 1 つのデータ コントラクトであるかのように扱われます。 データ メンバーの順序は一致する必要があり、基本型メンバーは派生型メンバーの順序の前に置く必要があることに注意してください。 さらに、次のコード例のように、2 つのデータ メンバーの順序値が同じ場合、それらのデータ メンバーの順序はアルファベット順になります。 詳細については、「 データ メンバーの順序」を参照してください。

次の例では、 Employee 型のデータ コントラクトは、 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}.

クライアントとサービスの間でパラメーターを渡して値を返す場合、受信側のエンドポイントが派生クラスからのデータ コントラクトを想定している場合、基底クラスからのデータ コントラクトを送信できません。 これは、オブジェクト指向プログラミングの教義に従います。 前の例では、Personが必要な場合、Employee型のオブジェクトを送信できません。

派生クラスからのデータ コントラクトは、基底クラスからのデータ コントラクトが必要な場合に送信できますが、受信エンドポイントが KnownTypeAttributeを使用して派生型を "認識" している場合にのみ送信できます。 詳細については、「 データ コントラクトの既知の型」を参照してください。 前の例では、 Employee 型のオブジェクトは、 Person が予期されるときに送信できますが、受信側コードが既知の型の一覧に含める KnownTypeAttribute を使用している場合にのみ送信できます。

アプリケーション間でパラメーターと戻り値を渡す場合、予期される型がインターフェイスの場合、予期される型が Object型であるのと同じです。 すべての型は最終的に Objectから派生するため、すべてのデータ コントラクトは最終的に Objectのデータ コントラクトから派生します。 したがって、インターフェイスが必要な場合は、任意のデータ コントラクト型を渡すことができます。 インターフェイスを正常に操作するには、追加の手順が必要です。詳細については、「 データ コントラクトの既知の型」を参照してください

こちらも参照ください