我正在尝试在使用Microsoft.FSharpLu.Json的项目中实现Giraffe.Serialization.Json的IJsonSerializer,但是遇到一种通用方法(下面的代码)的麻烦
type FSharpLuSerializer () =
interface Giraffe.Serialization.Json.IJsonSerializer with
member __.Deserialize<'T> (json : string) =
Microsoft.FSharpLu.Json.Default.deserialize<'T> json
我得到了错误
此代码不够通用。 类型变量^ T无法泛化,因为它会逃避其范围
我看到了其他具有相同错误的问题,但是我不确定如何将其解决方案应用于我的情况。我想这与使用^ T的FSharpLu.Json有关,但我不知道我的解决方法是什么
https://github.com/Microsoft/fsharplu/blob/master/FSharpLu.Json/Default.fs
这是长颈鹿IJSonSerializer界面
[<AllowNullLiteral>]
type IJsonSerializer =
abstract member SerializeToString<'T> : 'T -> string
abstract member SerializeToBytes<'T> : 'T -> byte array
abstract member SerializeToStreamAsync<'T> : 'T -> Stream -> Task
abstract member Deserialize<'T> : string -> 'T
abstract member Deserialize<'T> : byte[] -> 'T
abstract member DeserializeAsync<'T> : Stream -> Task<'T>
答案 0 :(得分:2)
遇到相同问题时,我遇到了这个问题。我只是写了这个,它似乎正在工作。我将以更多的速度运行它,如果一切顺利,我将推出一个NuGet软件包,可以将其插入。
return response()->download('patht-to-file', 'download.csv', ['Content-Type' => 'text/csv; charset=utf-8'])
也欢迎来自F#人士的反馈。
答案 1 :(得分:1)
跳到F#Slack之后,还有一种更简单的方法来执行此操作,不需要所有的装箱和投射。 FSharpLu在后台使用Newtonsoft.Json,其紧凑功能来自CompactUnionJsonConverter
类型。您可以将此转换器添加到Giraffe的默认JsonSerializerSettings
中,它可以工作-意味着您不必完全重新实现IJsonSerializer
。
open Giraffe.Serialization
open Microsoft.FSharpLu.Json
open Newtonsoft.Json
let jsonSettings =
let x = NewtonsoftJsonSerializer.DefaultSettings
x.Converters.Add (CompactUnionJsonConverter (true))
x
然后,在其中配置服务...
services.AddSingleton<IJsonSerializer>(NewtonsoftJsonSerializer jsonSettings)
非常感谢Nino Floris(@ninofloris)的建议。
答案 2 :(得分:0)
这是一个凌乱的接口,通常,接口需要捕获要通过方法上的泛型应用的类型,以进一步使事情复杂化,您的FSharpLu.Json库正在使用内联SRTP,SRTP内联模板,方法调用^约束类型,因此在编译后的代码中,每个调用都有一个concreate,固定类型方法,这不同于.net中用于在运行时解析该类型的普通化通用泛型。
由于无法内联接口,请尝试在该接口上添加类型约束,以捕获类型并避免泛化问题。
type IJsonSerializer<'T> =
abstract member SerializeToString : 'T -> string
...