다음을 통해 공유


데이터 계약 동등성

클라이언트가 서비스에 특정 형식의 데이터를 성공적으로 보내거나, 서비스에서 클라이언트에 데이터를 성공적으로 보내기 위해, 보낸 형식이 받는 측에 반드시 있어야 하는 것은 아닙니다. 두 형식의 데이터 계약이 일치하기만 하면 됩니다. (데이터 계약 버전 관리에 설명된 대로 엄격한 동등성이 필요하지 않은 경우도 있습니다.)

데이터 계약이 서로 같으려면 네임스페이스와 이름이 같아야 합니다. 또한 한 쪽의 각 데이터 멤버에 해당하는 데이터 멤버가 다른 쪽에 있어야 합니다.

데이터 멤버가 같으려면 이름이 같아야 합니다. 또한 데이터 멤버가 동일한 형식의 데이터를 나타내야 합니다. 즉, 해당 데이터 계약이 일치해야 합니다.

참고 항목

데이터 계약 이름 및 네임스페이스와 데이터 멤버 이름은 대/소문자를 구분합니다.

데이터 계약 이름과 네임스페이스, 데이터 멤버 이름에 대한 자세한 내용은 데이터 계약 이름을 참조하세요.

같은 쪽(발신자 또는 수신자)에 두 가지 형식이 있고 해당 데이터 계약이 다른 경우(예: 데이터 멤버가 서로 다른 경우) 동일한 이름과 네임스페이스를 지정하지 않아야 합니다. 그렇게 하면 예외가 throw될 수 있습니다.

다음 형식에 대한 데이터 계약은 서로 동등합니다.

[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

상속, 인터페이스 및 데이터 계약 동등성

동등성을 결정할 때 다른 데이터 계약으로부터 상속되는 데이터 계약은 기본 형식의 모든 데이터 멤버를 포함하는 데이터 계약처럼 처리됩니다. 데이터 멤버의 순서가 일치해야 하고, 기본 형식 멤버가 파생된 형식 멤버보다 앞에 와야 합니다. 또한 다음 코드 예제에서처럼 두 데이터 멤버의 순서 값이 동일한 경우 해당 데이터 멤버의 순서는 사전순으로 지정됩니다. 자세한 내용은 데이터 멤버 주문을 참조하세요.

다음 예제에서 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}.

클라이언트와 서비스 간에 매개 변수 및 반환 값을 전달할 때 수신하는 엔드포인트에 파생된 클래스의 데이터 계약이 필요한 경우 기본 클래스의 데이터 계약을 보낼 수 없습니다. 이는 개체 지향 프로그래밍 개념을 따릅니다. 이전 예에서 Employee가 필요한 경우 Person 형식 개체를 보낼 수 없습니다.

기본 클래스의 데이터 계약이 필요한 경우에 파생 클래스의 데이터 계약을 보낼 수 있지만, 수신하는 엔드포인트가 KnownTypeAttribute를 사용하여 파생 형식에 대해 "알고 있는" 경우에만 해당됩니다. 자세한 내용은 데이터 계약 알려진 형식을합니다. 이전 예제에서 Employee이 필요할 때 Person 형식 개체를 보낼 수 있지만, 수신기 코드에서 KnownTypeAttribute를 사용하여 알려진 형식 목록에 포함시키는 경우에만 해당됩니다.

애플리케이션 간에 매개 변수 및 반환 값을 전달할 때 필요한 형식이 인터페이스이면 Object 형식의 예상 형식과 동등합니다. 모든 형식이 궁극적으로 Object에서 파생되기 때문에 모든 데이터 계약은 궁극적으로 Object에 대한 데이터 계약에서 파생됩니다. 따라서 인터페이스가 필요할 때 모든 데이터 계약 형식을 전달할 수 있습니다. 추가 단계에 따라 인터페이스를 사용해야 합니다. 자세한 내용은 데이터 계약의 알려진 형식을 참조하세요.

참고 항목