2011-12-19 27 views
6

Trước tiên, tôi phải nói rằng tôi không biết sử dụng công cụ F # ​​cụ thể khi tích hợp với các ngôn ngữ khác trong .NET.F #, tuần tự hóa các công đoàn bị phân biệt đối xử với các giá trị thiếu dữ liệu

Vấn đề của tôi là tôi không hiểu cách tạo Tham chiếu dịch vụ cho một dịch vụ chứa các phương pháp phơi bày các công đoàn phân biệt đối xử.

tôi nhận được những điều cơ bản mà đi một chút gì đó như thế này:

type TelephonyProductActivationData = 
    | MobileUseNextIcc 
    | Mobile of decimal 
    | MobileBroadbandUseNextIcc 
    | MobileBroadband of decimal 
    | Fixed 
    | Voip of int16 * int16 
    static member KnownTypes() = 
     typeof<TelephonyProductActivationData>.GetNestedTypes(BindingFlags.Public ||| BindingFlags.NonPublic) |> Array.filter FSharpType.IsUnion 

Nếu bạn sử dụng F # tương tác đầu tiên tạo ra các loại:

type TelephonyProductActivationData = 
    | MobileUseNextIcc of unit 
    | Mobile of decimal<Icc> 
    | MobileBroadbandUseNextIcc of unit 
    | MobileBroadband of decimal<Icc> 
    | Fixed of unit 
    | Voip of BoxNr * int16<BoxPort>;; 

Và bạn thực hiện phần knowntypes mã (hơi được sửa đổi):

(typeof<TelephonyProductActivationData>.GetNestedTypes(System.Reflection.BindingFlags.Public ||| System.Reflection.BindingFlags.NonPublic) |> Array.filter Microsoft.FSharp.Reflection.FSharpType.IsUnion) |> Array.map (fun x -> x.FullName);; 

bạn sẽ thấy kết quả sau:

val it : string [] = 
    [|"FSI_0047+TelephonyProductActivationData+Mobile"; 
    "FSI_0047+TelephonyProductActivationData+MobileBroadband"; 
    "FSI_0047+TelephonyProductActivationData+Voip"|] 

Lưu ý rằng các giá trị không có dữ liệu được liên kết với chúng đã biến mất. Nó có nghĩa là không có loại nào sẽ được tạo ra khi biên dịch liên minh phân biệt này. Bằng cách thực hiện tuyên bố này trong F # tương tác:

typeof<TelephonyProductActivationData>.GetProperties() |> Array.map (fun x -> (x.Name));; 

chúng ta sẽ thấy những gì họ đã trở thành:

val it : string [] = 
    [|"Tag"; "IsVoip"; "Fixed"; "IsFixed"; "IsMobileBroadband"; 
    "MobileBroadbandUseNextIcc"; "IsMobileBroadbandUseNextIcc"; "IsMobile"; 
    "MobileUseNextIcc"; "IsMobileUseNextIcc"|] 

Như bạn có thể thấy các giá trị không có dữ liệu liên kết với chúng đã trở thành tài sản. Bây giờ tôi có thể cho bạn thấy vấn đề thực sự. Khi tạo một tài liệu tham khảo phục vụ cho các dịch vụ với phương pháp này tất cả tôi nhận được là:

[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] 
[System.Runtime.Serialization.DataContractAttribute(Name="ActivationModel.TelephonyProductActivationData", Namespace="http://schemas.datacontract.org/2004/07/Svea.Inri.Data")] 
[System.SerializableAttribute()] 
[System.Runtime.Serialization.KnownTypeAttribute(typeof(ConsoleApplication1.ServiceReference1.ActivationModelTelephonyProductActivationData.Mobile))] 
[System.Runtime.Serialization.KnownTypeAttribute(typeof(ConsoleApplication1.ServiceReference1.ActivationModelTelephonyProductActivationData.MobileBroadband))] 
[System.Runtime.Serialization.KnownTypeAttribute(typeof(ConsoleApplication1.ServiceReference1.ActivationModelTelephonyProductActivationData.Voip))] 
public partial class ActivationModelTelephonyProductActivationData : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged { 

    [System.NonSerializedAttribute()] 
    private System.Runtime.Serialization.ExtensionDataObject extensionDataField; 

    private int _tagField; 

    [global::System.ComponentModel.BrowsableAttribute(false)] 
    public System.Runtime.Serialization.ExtensionDataObject ExtensionData { 
     get { 
      return this.extensionDataField; 
     } 
     set { 
      this.extensionDataField = value; 
     } 
    } 

    [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)] 
    public int _tag { 
     get { 
      return this._tagField; 
     } 
     set { 
      if ((this._tagField.Equals(value) != true)) { 
       this._tagField = value; 
       this.RaisePropertyChanged("_tag"); 
      } 
     } 
    } 

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; 

    protected void RaisePropertyChanged(string propertyName) { 
     System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged; 
     if ((propertyChanged != null)) { 
      propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] 
    [System.Runtime.Serialization.DataContractAttribute(Name="ActivationModel.TelephonyProductActivationData.Mobile", Namespace="http://schemas.datacontract.org/2004/07/Svea.Inri.Data")] 
    [System.SerializableAttribute()] 
    public partial class Mobile : ConsoleApplication1.ServiceReference1.ActivationModelTelephonyProductActivationData { 

     private decimal itemField; 

     [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)] 
     public decimal item { 
      get { 
       return this.itemField; 
      } 
      set { 
       if ((this.itemField.Equals(value) != true)) { 
        this.itemField = value; 
        this.RaisePropertyChanged("item"); 
       } 
      } 
     } 
    } 

    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] 
    [System.Runtime.Serialization.DataContractAttribute(Name="ActivationModel.TelephonyProductActivationData.MobileBroadband", Namespace="http://schemas.datacontract.org/2004/07/Svea.Inri.Data")] 
    [System.SerializableAttribute()] 
    public partial class MobileBroadband : ConsoleApplication1.ServiceReference1.ActivationModelTelephonyProductActivationData { 

     private decimal itemField; 

     [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)] 
     public decimal item { 
      get { 
       return this.itemField; 
      } 
      set { 
       if ((this.itemField.Equals(value) != true)) { 
        this.itemField = value; 
        this.RaisePropertyChanged("item"); 
       } 
      } 
     } 
    } 

    [System.Diagnostics.DebuggerStepThroughAttribute()] 
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] 
    [System.Runtime.Serialization.DataContractAttribute(Name="ActivationModel.TelephonyProductActivationData.Voip", Namespace="http://schemas.datacontract.org/2004/07/Svea.Inri.Data")] 
    [System.SerializableAttribute()] 
    public partial class Voip : ConsoleApplication1.ServiceReference1.ActivationModelTelephonyProductActivationData { 

     private string item1Field; 

     private short item2Field; 

     [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)] 
     public string item1 { 
      get { 
       return this.item1Field; 
      } 
      set { 
       if ((object.ReferenceEquals(this.item1Field, value) != true)) { 
        this.item1Field = value; 
        this.RaisePropertyChanged("item1"); 
       } 
      } 
     } 

     [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)] 
     public short item2 { 
      get { 
       return this.item2Field; 
      } 
      set { 
       if ((this.item2Field.Equals(value) != true)) { 
        this.item2Field = value; 
        this.RaisePropertyChanged("item2"); 
       } 
      } 
     } 
    } 
} 

Không có lớp con ActivationModelTelephonyProductActivationData (phần ActivationModel là không gian tên) đại diện cho các giá trị không có bất kỳ dữ liệu và không có tính chất trong baseclass, nơi bạn có thể thiết lập các giá trị không có bất kỳ dữ liệu nào.

Câu hỏi của tôi là cuối cùng, làm thế nào là một trong những nghĩa vụ phải làm điều này. Tôi có phải thêm "của đơn vị" vào tất cả các giá trị công đoàn bị phân biệt đối xử không có dữ liệu của tôi không.

Trả lời

1

Về bản chất, bạn tùy thuộc vào chi tiết triển khai (dạng DU được biên dịch) để làm việc này. Thậm chí thay đổi từng trường hợp để có mùi không trống rỗng đối với tôi. Tôi nghĩ giải pháp lý tưởng là sử dụng các lớp học. Một DU xấp xỉ tương ứng với một lớp cơ sở trừu tượng cho kiểu DU và một lớp con cho mỗi trường hợp. Bạn có thể tự tạo phân cấp kiểu, đạt được hiệu ứng tương tự và nhận kết quả tốt hơn.

EDIT: Các hình thức biên soạn của dus, trong khi một chi tiết thực hiện, defined in the spec và do đó không thay đổi. Tuy nhiên, đặt ra các loại chính mình làm cho nó rõ ràng và ngăn cản bạn phải làm việc xung quanh trường hợp nullary.

3

Nếu bạn xác định loại DU như dưới đây, nó sẽ hoạt động.

[<KnownType("KnownTypes")>] 
//[<DataContract>] // note: keep KnownTypes, but avoid DataContract 
// so that DataContractSerializer uses .NET 'Serializable' instead 
type TelephonyProductActivationData = 
    | MobileUseNextIcc 
    | Mobile of decimal 
    | MobileBroadbandUseNextIcc 
    | MobileBroadband of decimal 
    | Fixed 
    | Voip of int16 * int16 
    static member KnownTypes() = 
     typeof<TelephonyProductActivationData>.GetNestedTypes(BindingFlags.Public ||| 
                  BindingFlags.NonPublic) 
     |> Array.filter FSharpType.IsUnion 
+0

Tôi đã bỏ lỡ điều đó trong bài đăng ở trên. Tất nhiên DU có thuộc tính knowntype. – Kristian

Các vấn đề liên quan