Bagikan melalui


Jenis yang Diketahui

Sampel KnownTypes menunjukkan cara menentukan informasi tentang jenis turunan dalam kontrak data. Kontrak data memungkinkan Anda meneruskan data terstruktur ke dan dari layanan. Dalam pemrograman berorientasi objek, jenis yang mewarisi dari jenis lain dapat digunakan sebagai pengganti jenis asli. Dalam pemrograman berorientasi layanan, skema daripada jenis dikomunikasikan dan oleh karena itu, hubungan antara jenis tidak dipertahankan. Atribut ini KnownTypeAttribute memungkinkan informasi tentang jenis turunan untuk disertakan dalam kontrak data. Jika mekanisme ini tidak digunakan, jenis turunan tidak dapat dikirim atau diterima di mana jenis dasar diharapkan.

Nota

Prosedur penyiapan dan instruksi build untuk sampel ini terletak di akhir topik ini.

Kontrak layanan untuk layanan menggunakan angka kompleks, seperti yang ditunjukkan dalam kode sampel berikut.

// 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);
}

DataContractAttribute dan DataMemberAttribute diterapkan ke ComplexNumber kelas untuk menunjukkan bidang kelas mana yang dapat diteruskan antara klien dan layanan. Kelas turunan ComplexNumberWithMagnitude dapat digunakan sebagai pengganti ComplexNumber. Atribut KnownTypeAttribute pada ComplexNumber jenis menunjukkan ini.

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

Jenis ComplexNumberWithMagnitude diturunkan dari ComplexNumber tetapi menambahkan anggota data tambahan, 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(); }
    }
}

Untuk menunjukkan fitur jenis yang diketahui, layanan diimplementasikan sedemikian rupa sehingga mengembalikan sebuah ComplexNumberWithMagnitude hanya untuk penambahan dan pengurangan. (Meskipun kontrak menentukan ComplexNumber, ini diizinkan karena KnownTypeAttribute atribut ). Perkalian dan pembagian masih mengembalikan jenis dasar ComplexNumber .

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

Pada klien, kontrak layanan dan kontrak data ditentukan dalam file sumber generatedClient.cs, yang dihasilkan oleh ServiceModel Metadata Utility Tool (Svcutil.exe) dari metadata layanan. Karena atribut KnownTypeAttribute ditentukan dalam kontrak data layanan, klien dapat menerima kelas ComplexNumber dan ComplexNumberWithMagnitude saat menggunakan layanan. Klien mendeteksi apakah ia mendapatkan ComplexNumberWithMagnitude dan menghasilkan output yang sesuai:

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

// Call the Add service operation.
ComplexNumber value1 = new ComplexNumber() { real = 1, imaginary = 2 };
ComplexNumber value2 = new ComplexNumber() { real = 3, 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");
}

Saat Anda menjalankan sampel, permintaan dan respons operasi ditampilkan di jendela konsol klien. Perhatikan bahwa besaran dicetak untuk penambahan dan pengurangan tetapi tidak untuk perkalian dan pembagian karena cara layanan diterapkan. Tekan ENTER di jendela klien untuk mematikan klien.

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.

Untuk menyiapkan, mengompilasi, dan menjalankan sampel

  1. Pastikan Anda telah melakukan Prosedur Penyiapan One-Time untuk Sampel Windows Communication Foundation.

  2. Untuk membangun solusi edisi C# atau Visual Basic .NET, ikuti instruksi di Membangun Sampel Windows Communication Foundation.

  3. Untuk menjalankan sampel dalam konfigurasi satu atau lintas komputer, ikuti instruksi di Menjalankan Sampel Windows Communication Foundation.