已知型別
這個範例會示範如何在資料合約中指定有關衍生型別的資訊。資料合約可以讓您在服務間來回傳遞結構化資料。在物件導向程式設計中,繼承自另一個型別的型別可以用來取代原始型別。在服務導向程式設計中,會使用結構描述而不是型別進行通訊,因此不會保留型別之間的關係。KnownTypeAttribute 屬性可以讓關於衍生型別的資訊包含到資料合約中。如果不使用這個機制,這時將無法傳送或接收衍生型別,因為預期是使用基底型別 (Base Type)。
注意: |
---|
此範例的安裝程序與建置指示位於本主題的結尾。 |
此服務的服務合約會使用複數,如下列範例程式碼所示。
// 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 和 DataMemberAttribute 會套用至 ComplexNumber
類別,以便指示可在用戶端與服務之間傳遞的類別欄位。衍生的 ComplexNumberWithMagnitude
類別可以用來取代 ComplexNumber
。ComplexNumber
型別的 KnownTypeAttribute 屬性會指示這項資訊。
[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;
}
}
ComplexNumberWithMagnitude
型別衍生自 ComplexNumber
,但是其新增額外的資料成員,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(); }
}
}
為了示範已知型別功能,此服務會實作成只傳回加法與減法的 ComplexNumberWithMagnitude
(雖然合約會指定 ComplexNumber
,但是因為 KnownTypeAttribute 屬性的關係,所以仍會允許這項行為)。乘法與除法仍然會傳回基底 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);
}
}
在用戶端上,服務合約與資料合約都會定義在原始程式檔 generatedClient.cs 中,而這個檔案是Service Metadata Utility Tool (Svcutil.exe) 從服務中繼資料所產生的。因為服務資料合約中是指定 KnownTypeAttribute 屬性,所以用戶端在使用服務時便能夠同時接收 ComplexNumber
和 ComplexNumberWithMagnitude
類別。用戶端會偵測其是否收到 ComplexNumberWithMagnitude
,然後產生適當的輸出:
// 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");
}
當您執行範例時,作業的要求和回應會顯示在用戶端主控台視窗中。請注意,此服務的實作方式會使得加法與減法列印值範圍,但是乘法與除法則不會列印。在用戶端視窗中按下 ENTER 鍵,即可關閉用戶端。
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.
若要設定、建置及執行範例
若要建置方案的 C# 或 Visual Basic .NET 版本,請遵循建置 Windows Communication Foundation 範例中的指示。
若要在單一或跨電腦的組態中執行本範例,請遵循執行 Windows Communication Foundation 範例中的指示。
Send comments about this topic to Microsoft.
© 2007 Microsoft Corporation. All rights reserved.