[英]F# Inheritance with Multiple Base Constructors and Events
目前有一个 F# class 实现如下:
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>()
我想知道是否有更简单的方法让 CLIEvent 与 let 绑定一起使用,并且仍然根据需要使用所有基本 class 构造函数,以最终摆脱 InitFields 方法。
恐怕你在这里无能为力。 问题在于,只有当您始终只调用单个基本 class 构造函数时,才能使用具有隐式构造函数的类的轻量级 F# 语法。 您的情况并非如此,因此您必须使用显式语法。
如果在构造函数的{.. }
部分初始化事件,则可以避免DefaultValue
属性,您可以在其中调用基本 class 构造函数并初始化所有字段。 这对您并没有太大帮助,但这是我能想到的唯一调整:
type A =
new (n:int) = {}
new (s:string) = {}
type B =
inherit A
new (n:int) = {
inherit A(n)
myFSharpEvent = new Event<_, _>() }
new (s:string) = {
inherit A(s)
myFSharpEvent = new Event<_, _>() }
val mutable myFSharpEvent : Event<EventHandler<EventArgs>,EventArgs>
member this.FSharpEvent = this.myFSharpEvent.Publish
member this.RaiseFSharpEvent e = this.myFSharpEvent.Trigger e
这会导致一些最小的代码重复 - 我认为这很好,但您也可以定义一个帮助程序 function (但在 class 之外,因为您不能在此类中使用let
)。
总结可能是,我将把所有重要的逻辑从这个 class 中移开,只把它当作一个包装器,以使我漂亮的 F# 代码与你需要的任何 .NET 基础设施兼容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.