2011-12-19 13 views
6

की कमी वाले मूल्यों के साथ भेदभाव वाले यूनियनों को क्रमबद्ध करना, सबसे पहले, मुझे यह कहना है कि मुझे पता है कि मुझे पता है कि आमतौर पर .NET में अन्य भाषाओं के साथ एकीकृत करते समय F # विशिष्ट सामग्री का उपयोग करना एक अच्छा विचार नहीं है।एफ #, डेटा

मेरी समस्या यह है कि मुझे समझ में नहीं आता कि भेदभाव वाले संघों को उजागर करने वाली विधियों वाली सेवा में सेवा संदर्भ कैसे बनाया जाए।

मैं मूल बातें है कि इस तरह एक छोटे से कुछ चला जाता है मिलती है:

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 

आप एफ # पहले प्रकार बनाने के लिए इंटरैक्टिव का उपयोग करते हैं:

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

और तुम knowntypes कोड भाग पर अमल (थोड़ा संशोधित):

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

आपको निम्न आउटपुट दिखाई देगा:

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

ध्यान दें कि उनके साथ जुड़े डेटा नहीं होने वाले मान चले गए हैं। इसका मतलब है कि इस भेदभाव संघ को संकलित करते समय कोई भी प्रकार नहीं बनाया जाएगा। एफ # में इस बयान इंटरैक्टिव क्रियान्वित द्वारा:

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

हम वे क्या बन गए हैं देखेंगे:

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

आप मान देख सकते हैं बिना उनसे संबद्ध डेटा गुण बन गए हैं। अब मैं आपको असली समस्या दिखा सकता हूं। जब इस विधि के साथ सेवा के लिए एक सेवा संदर्भ बनाने सब मैं यह है:

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

वहाँ ActivationModelTelephonyProductActivationData करने के लिए कोई उपवर्गों है (ActivationModel हिस्सा नाम स्थान है) है कि किसी भी डेटा नहीं होने मूल्यों का प्रतिनिधित्व करता है और वहाँ कोई गुण हैं बेसक्लास में जहां आप मूल्य निर्धारित कर सकते हैं जिसमें कोई डेटा नहीं है।

मेरा प्रश्न आखिरकार है, इसे कैसे करना है। क्या मुझे अपने सभी भेदभाव वाले यूनियन मूल्यों में "यूनिट" जोड़ना है जिसमें डेटा नहीं है।

उत्तर

1

आप अनिवार्य रूप से कार्यान्वयन विस्तार (डीयू के संकलित रूप) के आधार पर काम करने के लिए आवश्यक हैं। यहां तक ​​कि प्रत्येक मामले को गैर-नुकीली गंध करने के लिए मुझे भी हैकी बदलना। मुझे लगता है कि आदर्श समाधान कक्षाओं का उपयोग करना है। एक डीयू मोटे तौर पर डीयू प्रकार के लिए एक सार आधार वर्ग और प्रत्येक मामले के लिए एक उपclass के अनुरूप है। आप स्वयं पदानुक्रम प्रकार बना सकते हैं, एक समान प्रभाव प्राप्त कर सकते हैं, और बेहतर परिणाम प्राप्त कर सकते हैं।

संपादित: दस के संकलित रूप है, जबकि एक कार्यान्वयन विस्तार, defined in the spec और इसलिए परिवर्तन की संभावना नहीं है। हालांकि, प्रकारों को बिछाने से यह स्पष्ट हो जाता है और आपको निरर्थक मामलों के आसपास काम करने से रोकता है।

3

यदि आप नीचे दिए गए डीयू प्रकार को परिभाषित करते हैं, तो यह काम करेगा।

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

मुझे उपरोक्त मेरी पोस्ट में याद आया। बेशक डीयू के पास ज्ञात विशेषता थी। – Kristian