Bekannte TypenKnown Types

In diesem Beispiel wird veranschaulicht, wie Informationen über abgeleitete Typen in einem Datenvertrag angegeben werden.This sample demonstrates how to specify information about derived types in a data contract. Datenverträge ermöglichen es Ihnen, strukturierte Daten an Dienste zu übergeben und von ihnen zu empfangen.Data contracts allow you to pass structured data to and from services. In objektorientierten Programmierungen kann anstelle des ursprünglichen Typs ein Typ verwendet werden, der von einem anderen Typ erbt.In object-oriented programming, a type that inherits from another type can be used in place of the original type. In dienstorientierten Programmierungen werden Schemas und keine Typen kommuniziert, weshalb die Beziehung zwischen Typen nicht beibehalten wird.In service-oriented programming, schemas rather than types are communicated and therefore, the relationship between types is not preserved. Das KnownTypeAttribute-Attribut ermöglicht es, Informationen über abgeleitete Typen in den Datenvertrag einzubinden.The KnownTypeAttribute attribute allows information about derived types to be included in the data contract. Wenn dieser Mechanismus nicht verwendet wird, kann ein abgeleiteter Typ nicht gesendet oder empfangen werden, wenn ein Basistyp erwartet wird.If this mechanism is not used, a derived type cannot be sent or received where a base type is expected.

Hinweis

Die Setupprozedur und die Buildanweisungen für dieses Beispiel befinden sich am Ende dieses Themas.The setup procedure and build instructions for this sample are located at the end of this topic.

Der Dienstvertrag für den Dienst verwendet komplexe Zahlen, wie im folgenden Beispielcode gezeigt.The service contract for the service uses complex numbers, as shown in the following sample code.

// Define a service contract.  
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]  
public interface ICalculator  
{  
    [OperationContract]  
    ComplexNumber Add(ComplexNumber n1, ComplexNumber n2);  
    [OperationContract]  
    ComplexNumber Subtract(ComplexNumber n1, ComplexNumber n2);  
    [OperationContract]  
    ComplexNumber Multiply(ComplexNumber n1, ComplexNumber n2);  
    [OperationContract]  
    ComplexNumber Divide(ComplexNumber n1, ComplexNumber n2);  
}  

Das DataContractAttribute und DataMemberAttribute wird auf die ComplexNumber-Klasse angewendet, um anzugeben, welche Felder der Klasse zwischen dem Client und dem Dienst übergeben werden können.The DataContractAttribute and DataMemberAttribute is applied to the ComplexNumber class to indicate which fields of the class can be passed between the client and the service. Die abgeleitete ComplexNumberWithMagnitude-Klasse kann anstelle von ComplexNumber verwendet werden.The derived ComplexNumberWithMagnitude class can be used in place of ComplexNumber. Dies wird durch das KnownTypeAttribute-Attribut auf dem ComplexNumber-Typ angezeigt.The KnownTypeAttribute attribute on the ComplexNumber type indicates this.

[DataContract(Namespace="http://Microsoft.ServiceModel.Samples")]  
[KnownType(typeof(ComplexNumberWithMagnitude))]  
public class ComplexNumber  
{  
    [DataMember]  
    public double Real = 0.0D;  
    [DataMember]  
    public double Imaginary = 0.0D;  

    public ComplexNumber(double real, double imaginary)  
    {  
        this.Real = real;  
        this.Imaginary = imaginary;  
    }  
}  

Der ComplexNumberWithMagnitude-Typ wird von ComplexNumber abgeleitet, fügt aber einen zusätzlichen Datenmember, Magnitude, hinzu.The ComplexNumberWithMagnitude type derives from ComplexNumber but adds an additional data member, Magnitude.

[DataContract(Namespace="http://Microsoft.ServiceModel.Samples")]  
public class ComplexNumberWithMagnitude : ComplexNumber  
{  
    public ComplexNumberWithMagnitude(double real, double imaginary) :  
        base(real, imaginary) { }  

    [DataMember]  
    public double Magnitude  
    {  
        get { return Math.Sqrt(Imaginary*Imaginary  + Real*Real); }  
        set { throw new NotImplementedException(); }  
    }  
}  

Zur Veranschaulichung der Funktion bekannte Typen wird der Dienst so implementiert, bei der Rückgabe eine ComplexNumberWithMagnitude für Addition und Subtraktion.To demonstrate the known types feature, the service is implemented in such a way that it returns a ComplexNumberWithMagnitude only for addition and subtraction. (Obwohl der Vertrag ComplexNumber angibt, ist dies aufgrund des KnownTypeAttribute-Attributs zulässig).(Even though the contract specifies ComplexNumber, this is allowed because of the KnownTypeAttribute attribute). Multiplikation und Division weiterhin die Basis zurückgegeben ComplexNumber Typ.Multiplication and division still return the base ComplexNumber type.

public class DataContractCalculatorService : IDataContractCalculator  
{  
    public ComplexNumber Add(ComplexNumber n1, ComplexNumber n2)  
    {  
        //Return the derived type.  
        return new ComplexNumberWithMagnitude(n1.Real + n2.Real,  
                                      n1.Imaginary + n2.Imaginary);  
    }  

    public ComplexNumber Subtract(ComplexNumber n1, ComplexNumber n2)  
    {  
        //Return the derived type.  
        return new ComplexNumberWithMagnitude(n1.Real - n2.Real,   
                                 n1.Imaginary - n2.Imaginary);  
    }  

    public ComplexNumber Multiply(ComplexNumber n1, ComplexNumber n2)  
    {  
        double real1 = n1.Real * n2.Real;  
        double imaginary1 = n1.Real * n2.Imaginary;  
        double imaginary2 = n2.Real * n1.Imaginary;  
        double real2 = n1.Imaginary * n2.Imaginary * -1;  
        //Return the base type.  
        return new ComplexNumber(real1 + real2, imaginary1 +   
                                                  imaginary2);  
    }  

    public ComplexNumber Divide(ComplexNumber n1, ComplexNumber n2)  
    {  
        ComplexNumber conjugate = new ComplexNumber(n2.Real,   
                                     -1*n2.Imaginary);  
        ComplexNumber numerator = Multiply(n1, conjugate);  
        ComplexNumber denominator = Multiply(n2, conjugate);  
        //Return the base type.  
        return new ComplexNumber(numerator.Real / denominator.Real,  
                                             numerator.Imaginary);  
    }  
}  

Auf dem Client in der Quelle Datei "generatedclient.cs", die von generiert wird definiert den Dienstvertrag und den Datenvertrag der ServiceModel Metadata Utility Tool (Svcutil.exe) aus Dienstmetadaten.On the client, both the service contract and the data contract are defined in the source file generatedClient.cs, which is generated by the ServiceModel Metadata Utility Tool (Svcutil.exe) from service metadata. Da das KnownTypeAttribute-Attribut im Datenvertrag des Diensts angegeben ist, kann der Client sowohl die ComplexNumber-Klasse als auch die ComplexNumberWithMagnitude-Klasse empfangen, wenn er diesen Dienst verwendet.Because the KnownTypeAttribute attribute is specified in the service's data contract, the client is able to receive both the ComplexNumber and ComplexNumberWithMagnitude classes when using the service. Der Client erkennt, ob es eine ComplexNumberWithMagnitude abgerufen hat und generiert die entsprechende Ausgabe:The client detects whether it got a ComplexNumberWithMagnitude and generate the appropriate output:

// Create a client  
DataContractCalculatorClient client =   
    new DataContractCalculatorClient();  

// Call the Add service operation.  
ComplexNumber value1 = new ComplexNumber(); value1.real = 1; value1.imaginary = 2;  
ComplexNumber value2 = new ComplexNumber(); value2.real = 3; value2.imaginary = 4;  
ComplexNumber result = client.Add(value1, value2);  
Console.WriteLine("Add({0} + {1}i, {2} + {3}i) = {4} + {5}i",  
    value1.real, value1.imaginary, value2.real, value2.imaginary,  
    result.real, result.imaginary);  
if (result is ComplexNumberWithMagnitude)  
{  
    Console.WriteLine("Magnitude: {0}",   
        ((ComplexNumberWithMagnitude)result).Magnitude);  
}  
else  
{  
    Console.WriteLine("No magnitude was sent from the service");  
}  

Wenn Sie das Beispiel ausführen, werden die Anforderungen und Antworten des Vorgangs im Konsolenfenster des Clients angezeigt.When you run the sample, the requests and responses of the operation are displayed in the client console window. Beachten Sie, dass für Addition und Subtraktion ein Betrag angezeigt wird. Für Multiplikation und Division wird aufgrund der Implementierungsart des Diensts kein Betrag angezeigt.Note that a magnitude is printed for addition and subtraction but not for multiplication and division because of the way the service was implemented. Drücken Sie im Clientfenster die EINGABETASTE, um den Client zu schließen.Press ENTER in the client window to shut down the client.

Add(1 + 2i, 3 + 4i) = 4 + 6i  
Magnitude: 7.21110255092798  
Subtract(1 + 2i, 3 + 4i) = -2 + -2i  
Magnitude: 2.82842712474619  
Multiply(2 + 3i, 4 + 7i) = -13 + 26i  
No magnitude was sent from the service  
Divide(3 + 7i, 5 + -2i) = 0.0344827586206897 + 41i  
No magnitude was sent from the service  

    Press <ENTER> to terminate client.  

So können Sie das Beispiel einrichten, erstellen und ausführenTo set up, build, and run the sample

  1. Stellen Sie sicher, dass Sie ausgeführt haben die Setupprozedur für die Windows Communication Foundation-Beispiele zum einmaligen.Ensure that you have performed the One-Time Setup Procedure for the Windows Communication Foundation Samples.

  2. Um die C#- oder Visual Basic .NET-Edition der Projektmappe zu erstellen, befolgen Sie die unter Building the Windows Communication Foundation Samplesaufgeführten Anweisungen.To build the C# or Visual Basic .NET edition of the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  3. Um das Beispiel in einer einzelnen oder computerübergreifenden Konfiguration ausführen möchten, folgen Sie den Anweisungen Ausführen der Windows Communication Foundation-Beispiele.To run the sample in a single- or cross-machine configuration, follow the instructions in Running the Windows Communication Foundation Samples.

Wichtig

Die Beispiele sind möglicherweise bereits auf dem Computer installiert.The samples may already be installed on your machine. Suchen Sie nach dem folgenden Verzeichnis (Standardverzeichnis), bevor Sie fortfahren.Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

Wenn dieses Verzeichnis nicht vorhanden ist, fahren Sie mit Windows Communication Foundation (WCF) und Windows Workflow Foundation (WF) Samples for .NET Framework 4 aller Windows Communication Foundation (WCF) herunterladen und WFWF Beispiele.If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WFWF samples. Dieses Beispiel befindet sich im folgenden Verzeichnis.This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WCF\Basic\Contract\Data\KnownTypes

Siehe auchSee Also