我有一个问题,我正在尝试基于 f# 中的 singelton 创建某种调解器。主要原因是我需要在我的应用程序的一部分中注册一些操作并在另一个类似于 c# 的部分中执行它,如下所示:
public class Mediator
{
private static readonly object syncRoot = new object();
private static Mediator instance;
public static Mediator Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
{
instance = new Mediator();
}
}
}
return instance;
}
}
public event Action<string> InputLogUpdate;
public void InvokeInputLogUpdate(string msg)
{
InputLogUpdate?.Invoke(msg);
}
}
调用看起来像:
Mediator.Instance.InvokeInputLogUpdate(msg);
注册看起来像:
Mediator.Instance.InputLogUpdate += msg => this.DebugSection += $"{msg} \n";
但就目前而言,没有运气,我所拥有的只是:
vnamespace Operation.Mediator
module Mediator =
open System
type UdpMediator private () =
static let instance = UdpMediator()
let mutable UpdateDebigLog : Action<string> = null
static member Instance = instance
member this.InvokeUpdateLog (msg:string) = UpdateDebigLog.Invoke(msg)
而且效果不是很好,有人知道怎么做吗?
最佳答案
第一 , lock
的模式夹在两个 null
之间支票太陈旧了,我什至不记得我最后一次看到它是什么时候了。现代 .NET 有 Lazy<T>
对于这种按需初始化。而且,幸运的是,F# 实际上有它的特殊语法:
type UpdMediator private () =
static member val private _instance = lazy UpdMediator()
static member Instance = UpdMediator._instance.Value
第二 , 一个
event Action<_>
在 C# 中不等于 mutable Action<_>
在 F# 中。一个 event
C# 中的声明实际上创建了两个访问器方法 - add
和 remove
, - 就像 get
和 set
与属性。不过,F#其实有更好的机制——
Event<_>
.您将该类型的实例设为私有(private),然后通过它的.Publish
公开它。属性,类型为 IEvent<_>
.消费者可以使用 IEvent
添加和删除处理程序的值,或订阅可观察样式的事件(因为 IEvent
继承自 IObservable
):type UpdMediator private () =
...
member val private _updDebugLog = Event<string>()
member this.UpdDebugLog = this._updDebugLog.Publish
member this.InvokeUpdDebugLog() = this._updDebugLog.Trigger "foo"
// usage:
UpdMediator.Instance.UpdDebugLog.AddHandler (fun sender str -> printfn "%s" str)
// Or observable-style:
UpdMediator.Instance.UpdDebugLog.Subscribe (printfn "%s")
(注意
.Subscribe
返回一个 IDisposable
,以后可以用来取消订阅)第三 ,尝试将 C# 实践逐字翻译成 F# 通常不会有好的结果。 F# 通常比 C# 具有更好的功能,因此如您的案例所示,逐字翻译通常会有点尴尬。
最后,请注意,“不能很好地工作”并不是对问题的良好描述。如果您希望从社区中获得指导或建议,请花时间描述问题的具体内容、您预期会发生什么、您如何尝试实现它等等。请引用the SO "How to Ask" guide一些提示。
关于f# - F# 中的中介操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57758150/