[英]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.