Compartir a través de


Equivalencia del contrato de datos

Para que un cliente envíe correctamente datos de un cierto tipo a un servicio, o para que un servicio envíe correctamente datos a un cliente, el tipo enviado no tiene que existir necesariamente en el extremo receptor. El único requisito es que los contratos de datos de ambos tipos sean equivalentes. (En ocasiones, no se requiere la equivalencia estricta, como se explica en Versiones de contratos de datos.)

Para que los contratos de datos sean equivalentes, deben incluir el mismo espacio de nombres y nombre. Además, cada miembro de datos en un lado debe tener un miembro de datos equivalente en el otro.

Para que los miembros de datos sean equivalentes, deben tener el mismo nombre. De manera adicional, deben representar el mismo tipo de datos; es decir, sus contratos de datos deben ser equivalentes.

ms734767.note(es-es,VS.100).gifNota:
Tenga en cuenta que los nombres y espacios de nombres de contrato de datos, así como los nombres del miembros de datos, distinguen entre mayúsculas y minúsculas.

Para obtener más información sobre nombres y espacios de nombres de contratos de datos, así como los nombres del miembro de datos, vea Nombres de contratos de datos.

Si dos tipos existen en el mismo lado (remitente o receptor) y sus contratos de datos no son equivalentes (por ejemplo, tienen diferentes miembros de datos), no debería darles el mismo nombre y espacio de nombres. Si lo hace, pueden iniciarse excepciones.

Los contratos de datos de los tipos siguientes son equivalentes:

<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
[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;
}

Orden del miembro de datos y equivalencia del contrato de datos

Utilizar la propiedad Order de la clase DataMemberAttribute puede afectar a la equivalencia del contrato de datos. Los contratos de datos deben tener miembros que aparecen en el mismo orden para ser equivalentes. El orden predeterminado es alfabético. Para obtener más información, vea Orden de los miembros de datos.

Por ejemplo, el código siguiente produce contratos de datos equivalentes.

<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 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.
}

Sin embargo, el siguiente código no produce un contrato de datos equivalente.

<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
[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.
}

Herencia, interfaces y equivalencia del contrato de datos

Al determinar la equivalencia, un contrato de datos que hereda de otro contrato de datos se trata como si fuese, simplemente, un contrato de datos que incluye todos los miembros de datos del tipo base. Tenga presente que el orden de los miembros de datos debe coincidir y que los miembros de tipo base preceden, en el orden, a los miembros de tipo derivado. Además, si, como en el ejemplo de código siguiente, dos miembros de datos tienen el mismo valor de orden, la clasificación de esos miembros de datos será alfabética. Para obtener más información, vea Orden de los miembros de datos.

En el ejemplo siguiente, el contrato de datos para el tipo Employee es equivalente al contrato de datos para el tipo Worker.

<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}.
[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}.

Cuando se pasan parámetros y valores devueltos entre un cliente y un servicio, no se puede enviar un contrato de datos de una clase base si el extremo receptor espera un contrato de datos de una clase derivada. Esto es conforme con los principios de la programación orientada a objetos. En el ejemplo anterior, no se puede enviar un objeto de tipo Person si se espera Employee .

Se puede enviar un contrato de datos de una clase derivada si se espera un contrato de datos de una clase base, pero solo si el extremo receptor "conoce" el tipo derivado mediante KnownTypeAttribute. Para obtener más información, vea Tipos conocidos de contratos de datos. En el ejemplo anterior, se puede enviar un objeto de tipo Employee si se espera un Person, aunque solo si el código del receptor utiliza KnownTypeAttribute para incluirlo en la lista de tipos conocidos.

Al pasar parámetros y valores devueltos entre las aplicaciones, si el tipo esperado es una interfaz, es equivalente a cuando el tipo esperado es Object. Dado que, en última instancia, cada tipo deriva de Object, todos los contratos de datos derivan, a la larga, del contrato de datos para Object. De este modo, se puede pasar cualquier tipo de contrato de datos cuando se espera una interfaz. Son necesarios algunos pasos adicionales para trabajar correctamente con interfaces; para más información, vea Tipos conocidos de contratos de datos.

Vea también

Referencia

DataContractAttribute
DataMemberAttribute

Conceptos

Orden de los miembros de datos
Tipos conocidos de contratos de datos
Nombres de contratos de datos