我在尝试在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);
}
}
Run Code Online (Sandbox Code Playgroud)
调用看起来像:
Mediator.Instance.InvokeInputLogUpdate(msg);
Run Code Online (Sandbox Code Playgroud)
注册看起来像:
Mediator.Instance.InputLogUpdate += msg => this.DebugSection += $"{msg} \n";
Run Code Online (Sandbox Code Playgroud)
但是到目前为止,我所没有的是:
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)
Run Code Online (Sandbox Code Playgroud)
而且它不能很好地工作,有人知道该怎么做吗?
首先,lock夹在两张null支票之间的模式过时了,我什至不记得上次看到一张支票了。现代.NET具有Lazy<T>这种按需初始化的功能。而且,幸运的是,F#实际上具有特殊的语法:
type UpdMediator private () =
static member val private _instance = lazy UpdMediator()
static member Instance = UpdMediator._instance.Value
Run Code Online (Sandbox Code Playgroud)
其次,event Action<_>C#中的an 不等同mutable Action<_>于F#。eventC#中的声明实际上会创建两个访问器方法- add和和remove- get和set具有属性一样。
但是,F#实际上具有更好的机制- Event<_>。您将该类型的实例设为私有,然后通过其.Publish具有type的属性将其公开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")
Run Code Online (Sandbox Code Playgroud)
(请注意,.Subscribe返回IDisposable,可在以后取消订阅)
第三,尝试将C#实践逐字转换为F#通常效果不佳。F#通常比C#具有更好的功能,因此,如您的案例所示,逐词翻译通常会有些尴尬。
最后,请注意“不能很好地工作”不是对问题的良好描述。如果您希望收到社区的指导或建议,请花点时间描述问题的确切含义,预期会发生的情况以及如何解决该问题,等等。请参考SO“如何询问”指南以获取一些提示。
| 归档时间: |
|
| 查看次数: |
70 次 |
| 最近记录: |