【发布时间】:2022-01-27 23:06:17
【问题描述】:
我正在尝试在 F# Record 上实现 Microsoft.Extensions.Logging.ILogger(为简洁起见,复制如下)
using System;
namespace Microsoft.Extensions.Logging
{
public interface ILogger
{
void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter);
bool IsEnabled(LogLevel logLevel);
IDisposable BeginScope<TState>(TState state);
}
}
这是记录实现。
type ILoggerRcd<'TState> =
{
BeginScope : 'TState -> IDisposable
IsEnabled : LogLevel -> bool
Log : LogLevel * EventId * 'TState * exn * Func<'TState,exn,string> -> unit
}
interface ILogger with
override this.BeginScope(state : 'TState): IDisposable =
this.BeginScope (state)
override this.IsEnabled(logLevel: LogLevel): bool =
this.IsEnabled logLevel
override this.Log(logLevel: LogLevel, eventId: EventId, state : 'TState, ``exception``: exn, formatter: Func<'TState,exn,string>): unit =
this.Log(logLevel, eventId, state, ``exception``, formatter)
但是,我在 BeginScope 上收到此错误:One or more of the explicit class or function type variables for this binding could not be generalized, because they were constrained to other types。
日志中出现此错误:The generic member 'Log' has been used at a non-uniform instantiation prior to this program point. Consider reordering the members so this member occurs first. Alternatively, specify the full type of the member explicitly, including argument types, return type and any additional generic parameters and constraints.
我已经阅读了一些关于 fsharp 编译器本身的问题,但似乎没有什么是我遇到的这种情况。这是可以做到的吗?
【问题讨论】:
-
您是否尝试过让记录中的字段名称与 ILogger 的成员名称不同?不确定这是否会使编译器感到困惑。