Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

105
Views
Implementación de una interfaz con un parámetro genérico en un registro F#

Estoy tratando de implementar un Microsoft.Extensions.Logging.ILogger (copiado a continuación por brevedad) en un registro F #

 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); } }

Esta es la implementación del registro.

 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)

Sin embargo, recibo este error en 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 .

Y este error en Registro: 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.

He leído algunos problemas en el compilador fsharp, pero nada parece ser exactamente este caso. ¿Es esto algo que se puede hacer?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

La interfaz ILogger requiere que pueda registrar objetos de cualquier tipo, pero está tratando de registrar solo aquellos del tipo 'TState .

Tome la firma de BeginScope :

 IDisposable BeginScope<TState>(TState state);

¿Ves ese bit <TState> allí? Ese es un parámetro genérico. Esta firma significa que cada vez que alguien llama a este método, puede elegir un tipo de TState para usar con esa llamada.

Nuevamente: la persona que llama elige el tipo genérico, no el implementador.

Por ejemplo:

 let l : ILogger = ... l.BeginScope 42 // TState = int l.BeginScope true // TState = bool

Esto significa que su implementación de BeginScope debe poder funcionar con cualquier tipo, no solo con el tipo con el que se creó su registro ILoggerRcd .

over 4 years ago · Santiago Trujillo Report

0

El problema aquí es que está tratando de restringir el 'TState ILogger ILogger para que coincida con el ' ILoggerRcd 'TState , pero no es su elección hacerlo.

Para ver esto, tenga en cuenta que una persona que llama a ILogger.BeginScope puede pasar un estado int en una llamada y luego un estado de string en otra llamada a la misma instancia de ILogger . Su implementación intenta evitar esto, de ahí los errores del compilador.

La única forma en que puedo ver esto es usar métodos genéricos en su tipo en lugar de un registro de funciones. No creo que haya ninguna forma de hacer lo que quieras usando registros F # de vainilla.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!