c# - 具有多个基本构造函数和事件的 F# 继承
问题描述
目前有一个像这样实现的 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>()
我想知道是否有一种更简单的方法让 CLIEvent 与 let 绑定一起工作,并且仍然根据需要使用所有基类构造函数来最终摆脱 InitFields 方法。
解决方案
恐怕你在这里无能为力。问题是,只有当您总是只调用一个基类构造函数时,才能使用具有隐式构造函数的类的轻量级 F# 语法。您的情况并非如此,因此您必须使用显式语法。
DefaultValue
如果在构造函数部分初始化事件,则可以避免该属性{ .. }
,您可以在其中调用基类构造函数并初始化所有字段。这对您并没有太大帮助,但这是我能想到的唯一调整:
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
这会导致一些最小的代码重复——我认为这很好,但你也可以定义一个辅助函数(但在类之外,因为你不能let
在这个类中使用)。
总结可能是我将把所有重要的逻辑从这个类中移走,只把它当作一个包装器来使我漂亮的 F# 代码与你需要的任何 .NET 基础结构兼容。
推荐阅读
- android - 如何从 android studio 4.1 获取保存的密码
- ios - 呈现 ViewController 的问题
- ios - 使用 ionic 构建 ios 应用程序时出错
- url - Google 表单从电子表格中获取用户名,然后为每个用户提供一个唯一的 URL
- python - Python中每个单词的第二个字母大写
- javascript - React context api,将数据从孩子传递给父母
- reactjs - 使用对象映射和额外组件反应条件渲染
- python - 无法从我在 docker 容器下运行的应用程序连接到 localhost:8000 的快速 api 服务器
- python - 在 anaconda 中安装 GLIBCXX_3.4.29
- reactjs - 带有 React 的 AWS S3 预签名 URL 上传空文件