当第 3 方库需要 byref 作为输出参数时,c# 到 f#

c# to f# when 3rd party lib wants a byref as an out parameter

我正在尝试将此方法转换为 F#

private static bool VerifySignedJwt(ECDsa eCDsa, string token) {
    var tokenHandler = new JwtSecurityTokenHandler();
    var claimsPrincipal = tokenHandler.ValidateToken(token, new TokenValidationParameters {
        ValidIssuer = "me",
        ValidAudience = "you",
        IssuerSigningKey = new ECDsaSecurityKey(eCDsa)
    }, out var parsedToken);
    return claimsPrincipal.Identity.IsAuthenticated;
}

我正在翻译 Scott Brady 的这部伟大作品,以便为 Web 应用程序创建和验证 JWT 令牌,创建部分顺利进行。关于验证部分和对 JwtSecurityTokenHandler.ValidateToken 方法中所需的 byref 的引用让我很困惑。 https://www.scottbrady91.com/C-Sharp/JWT-Signing-using-ECDSA-in-dotnet-Core

如果我遵循下面的 Microsoft 文档;我收到一条错误消息,提示“类型实例化涉及 byref 类型。这是 Common IL 规则所不允许的。” 尝试将 byref 声明为:

let _h (x: byref<'T>) = ()

https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/byrefs 我已经阅读了关于 byrefs 的 Microsoft 文档,但我想知道这是否与 .Net 核心或 F#4.5 相关,或者 dotnet 核心是否取代了 F#4.5 中包括 byrefs 在内的所有功能? 无论哪种方式,我似乎都无法实例化 SecurityToken, "out var parsedToken" 是一种 SecurityToken 类型,更不用说用作此第 3 方库的输出的 byref 类型,或者我似乎无法在对 JwtSecurityTokenHandler.ValidateToken.[= 的调用中直接声明 byref SecurityToken 16=]

如果我使用此 SO post 中的建议 post Using c# delegates with f# functions

let function_1 (x:double) (y:double byref) = 
    y <- 6.0

我得到同样的错误 “类型实例化涉及一个 byref 类型。这是 Common IL 规则所不允许的。”

我以前在 F# 中使用过 Byrefs,但这些都是简单的整数类型并且可以正常工作。 我的项目是.Net core 2.1

感谢任何帮助。

由于 ValidateToken() 调用中的 out 参数是最后一个参数,您可以简单地省略它,并将其视为第二个 return 值:

let claimsPrincipal, parsedToken = tokenHandler.ValidateToken (token, tvp)

(此处 tvp 将是您的 TokenValidationParameters 实例。)

另请参阅 https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/parameters-and-arguments#passing-by-reference 了解更多信息。

编辑: 由于您似乎没有使用第二个 return 值,我认为您的函数可能如下所示:

let verifySignedJwt ecdsa token =
    let tokenHandler = JwtSecurityTokenHandler ()
    let tvp = TokenValidationParameters (ValidIssuer = "me",
                                         ValidAudience = "you",
                                         IssuerSigningKey = ECDsaSecurityKey ecdsa)
    let claimsPrincipal, _ = tokenHandler.ValidateToken (token, tvp)
    claimsPrincipal.Identity.IsAuthenticated

另一种选择(不一定更好)是这样的:

let mutable parsedToken = initialValue

let claimsPrinciple = tokenHandler.ValidateToken(token, tvp, &parsedToken)

// something with both

如果您有多个 byref 参数,或者最后没有单个 byref 参数的模式,以上内容很有用。