F#对象表达式能否自引用?——C#转F#的实例创建需求
F#对象表达式实现自引用CreateNewInstance的方案
直接用对象表达式没法在内部直接引用自身匿名类型创建新实例,但可以通过工厂函数配合对象表达式的方式实现需求,完美适配你提到的“大量这类类需要实现”的场景。
核心思路
对象表达式是匿名类型,没法在内部用new 类型()的方式生成自身实例,但可以把创建逻辑抽成外部工厂函数,在CreateNewInstance方法里调用这个工厂函数,从而返回同类型的新实例。
代码示例
假设外部库的IWorker接口在F#中映射后定义如下:
type IWorker = abstract member CreateNewInstance : unit -> IWorker
基础实现
先封装通用的工厂函数,把对象表达式的创建逻辑复用起来:
// 工厂函数:创建IWorker实例,支持传入自定义初始化逻辑 let createWorker (init: unit -> unit) = { new IWorker with member this.CreateNewInstance() = // 调用工厂函数生成同逻辑的新实例 createWorker init } |> fun worker -> // 执行当前实例的初始化逻辑 init() worker
之后创建不同的Worker实例就只需要写差异化的初始化逻辑,不用重复定义类:
// 创建WorkerA实例的入口 let createWorkerA () = createWorker (fun () -> // 这里写WorkerA专属的初始化逻辑,比如初始化字段、打印日志 printfn "Initializing WorkerA" ) // 创建WorkerB实例的入口 let createWorkerB () = createWorker (fun () -> printfn "Initializing WorkerB" )
测试效果:
let workerA = createWorkerA() let newWorkerA = workerA.CreateNewInstance() // 调用newWorkerA.CreateNewInstance()会再次生成WorkerA类型的新实例
带状态的扩展场景
如果Worker需要维护状态,只需把状态参数传入工厂函数即可:
type IStatefulWorker = abstract member State : int abstract member CreateNewInstance : unit -> IStatefulWorker let createStatefulWorker initialState = { new IStatefulWorker with member this.State = initialState member this.CreateNewInstance() = // 可复用当前初始状态,也可根据需求调整新实例的状态 createStatefulWorker initialState }
方案优势
相比C#中每个Worker都要定义独立类的方式,这种模式把重复的CreateNewInstance逻辑完全复用,只需要针对不同Worker编写差异化的初始化代码,极大减少了重复代码量,非常适合你“这类类数量较多”的场景。
内容的提问来源于stack exchange,提问作者Chris Long
相关产品推荐
相关产品推荐

