You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 15:45:32