首先,我不得不说,我知道在与.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

如果使用F#交互式首先创建类型:
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"|]

请注意,没有与之关联的数据的值都消失了。这意味着在编译此已区分的并集时不会创建任何类型。通过在F#交互中执行以下语句:
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部分是 namespace ),该子类表示不包含任何数据的值,并且在基类中没有可以设置不包含任何数据的属性。

最后,我的问题是,应该如何做到这一点。我是否必须在所有没有数据的已区分联合值中添加“单位”。

最佳答案

如果您按如下方式定义DU类型,则它将起作用。

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

10-08 06:30