c# - 在 F# 记录上实现具有泛型参数的接口(interface)

标签 c# .net logging f#

我正在尝试实现 Microsoft.Extensions.Logging.ILogger (为简洁起见在下面复制)在 F# Record

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'TState 以匹配 ILoggerRcd'TState ,但这不是您的选择。

要看到这一点,请注意 ILogger.BeginScope 的调用者可以在一次调用中传递一个 int 状态,然后传递一个 string 状态在对同一 ILogger 实例的另一次调用中。您的实现试图阻止这种情况,因此会出现编译器错误。

我能看到的解决这个问题的唯一方法是在您的类型中使用泛型方法而不是函数记录。我不认为有任何方法可以使用普通 F# 记录来做你想做的事。

关于c# - 在 F# 记录上实现具有泛型参数的接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70886932/

相关文章:

c# - Microsoft Service Fabric 和日志记录

java - 以编程方式从 log4j 获取日志事件

php - 运行时的 Log4Php 属性设置

c# - richtextbox 中每个单词的额外信息- richtextbox 和 sql 表之间的链接

c# - 通过C++或C#和Windows API创建Wi Fi网络

c# - linq 将 2 个表合并为一个列表

javascript - 单击 RadioButton 时关联的文本框

.net - 充分了解 .NET 版本和向后兼容性

c# - 我必须检查 Asp.Net 中的数据库中是否存在数据

C#:string[] 到定界字符串。有单线吗?