C# 具有多个基本构造函数和事件的F#继承

C# 具有多个基本构造函数和事件的F#继承,c#,.net,f#,C#,.net,F#,目前有一个F#类实现如下: namespace MultiLanguage.FSharpClassLibrary open MultiLanguage.CSharpClassLibrary open System open System.Runtime.Serialization [<Serializable>] type SerializableFSharpClass = inherit SerializableBaseClass new () as this

目前有一个F#类实现如下:

namespace MultiLanguage.FSharpClassLibrary

open MultiLanguage.CSharpClassLibrary
open System
open System.Runtime.Serialization

[<Serializable>]
type SerializableFSharpClass =
    inherit SerializableBaseClass

    new () as this =
        { inherit SerializableBaseClass() }
        then
        this.InitFields()

    new (other: SerializableFSharpClass) as this =
        { inherit SerializableBaseClass(other) }
        then
        this.InitFields()
        // Copy Properties

    new (info : SerializationInfo, context : StreamingContext) as this
        = { inherit SerializableBaseClass(info, context) } then
        this.InitFields()
        // Deserialize Properties

    // Let binding does not work
    // because of the following error:
    // FS0963: This definition may only be used in a type with a primary constructor.
    //let myFSharpEvent = new Event<EventHandler<EventArgs>,EventArgs>()
    //[<CLIEvent>]
    //member this.FSharpEvent = myFSharpEvent.Publish

    // Event raising does not work with member private
    // because new instances are created with every access to FSharpEvent:
    //member private this.myFSharpEvent = new Event<EventArgs>()
    //[<CLIEvent>]
    //member this.FSharpEvent = this.myFSharpEvent.Publish
    //member this.RaiseFSharpEvent e = this.myFSharpEvent.Trigger e

    // Event raising works with val mutable
    // but requires additional initialization of myFSharpEvent
    [<DefaultValue>]
    val mutable myFSharpEvent : Event<EventHandler<EventArgs>,EventArgs>
    [<CLIEvent>]
    member this.FSharpEvent = this.myFSharpEvent.Publish
    member this.RaiseFSharpEvent e = this.myFSharpEvent.Trigger e

    member private this.InitFields()
        =
        this.myFSharpEvent <- new Event<EventHandler<EventArgs>,EventArgs>()
namespace multi-language.FSharpClassLibrary
打开MultiLanguage.CSharpClassLibrary
开放系统
open System.Runtime.Serialization
[]
类型SerializableFSharpClass=
继承SerializableBaseClass
新的()如下所示=
{继承SerializableBaseClass()}
然后
this.InitFields()
新的(其他:SerializableFSharpClass)如下所示=
{继承SerializableBaseClass(其他)}
然后
this.InitFields()
//复制属性
新建(信息:SerializationInfo,上下文:StreamingContext)如下
={继承SerializableBaseClass(信息,上下文)}然后
this.InitFields()
//反序列化属性
//让绑定不起作用
//由于以下错误:
//FS0963:此定义只能在具有主构造函数的类型中使用。
//让myFSharpEvent=新事件()
//[]
//成员this.FSharpEvent=myFSharpEvent.Publish
//事件引发不适用于成员私有
//因为每次访问FSharpEvent都会创建新实例:
//成员private this.myFSharpEvent=新事件()
//[]
//成员this.FSharpEvent=this.myFSharpEvent.Publish
//成员this.RaiseFSharpEvent e=this.myFSharpEvent.Trigger e
//事件引发与val mutable一起工作
//但需要额外初始化myFSharpEvent
[]
val可变myFSharpEvent:事件
[]
成员this.FSharpEvent=this.myFSharpEvent.Publish
成员this.RaiseFSharpEvent e=this.myFSharpEvent.Trigger e
成员private this.InitFields()
=

this.myFSharpEvent恐怕你在这里无能为力。问题是,只有在始终只调用单个基类构造函数的情况下,才能使用具有隐式构造函数的类的轻量级F#语法。您的情况并非如此,因此必须使用显式语法

如果在构造函数的
{..}
部分初始化事件,则可以避免使用
DefaultValue
属性,在该部分可以调用基类构造函数,也可以初始化所有字段。这对你没有多大帮助,但这是我能想到的唯一的调整:

A型=
新的(n:int)={}
新的(s:string)={}
B型=
继承
新的(n:int)={
继承A(n)
myFSharpEvent=新事件()}
新(s:string)={
继承
myFSharpEvent=新事件()}
val可变myFSharpEvent:事件
成员this.FSharpEvent=this.myFSharpEvent.Publish
成员this.RaiseFSharpEvent e=this.myFSharpEvent.Trigger e
这将导致一些最小的代码重复-我认为这很好,但是您也可以定义一个helper函数(但是在类之外,因为您不能在这个类中使用
let

总结可能是,我会将所有重要的逻辑从这个类中移开,只将其作为一个包装器来处理,以使我漂亮的F#代码与您需要的任何.NET基础结构兼容